洛谷P1437 [HNOI2004]敲磚塊

由於上方和右上方都要打掉才能打這個位置,因此從第一行往下枚舉不能得到正確答案,所以考慮倒序枚舉,從最後一列按行枚舉ios

具體註釋看代碼ide

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<vector>
#include<string>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
const int N=55;
int n;
int m;
int a[N][N];
int f[N][N][N*(N+1)/2+1];
int main(){
    cin>>n>>m;
    memset(f,-0x3f,sizeof f);
    int i,j,k,l;
    f[n+1][0][0]=0; //只有這個位置是初始合法轉移位置 
    for(i=1;i<=n;i++) 
    for(j=1;j<=n-i+1;j++)
    cin>>a[i][j];
    for(i=n;i>=1;i--){ //從最後一列往前枚舉 
        int sum=0;
        for(j=0;j<=n-i+1;j++){ //0表明這一列不打,最多能夠打到n-i+1行 
        sum+=a[j][i];  //前綴和 
            for(k=j;k<=m;k++){ //至少要從j開始,最多打m個 
             for(l=max(0,j-1);l<=n-i;l++){ //由於右上方必需要打,因此至少是j-1,最多枚舉到前一列的最後一行 
                 f[i][j][k]=max(f[i][j][k],f[i+1][l][k-j]+sum);
             }    
            }
        }
    }
    int ans=0;
    for(i=1;i<=n;i++){
        for(j=0;j<=n-i+1;j++){
            ans=max(ans,f[i][j][m]);
        }
    }    
    cout<<ans<<endl;
}
View Code

 

沒有人不辛苦,只有人不喊疼
相關文章
相關標籤/搜索