洛谷P2331 [SCOI2005]最大子矩阵(BZOJ1084)

来源:互联网 发布:多文件上传java 编辑:程序博客网 时间:2024/06/14 15:08

DP

BZOJ题目传送门
洛谷题目传送门

m只有2啊。。。。乱搞就行了。。。
但是细节特别多。
f[i][j][k]表示前i行,状态为j用了k个矩阵时的最大值。

状态:
0:这一行不取
1:只取前一列
2:只取后一列
3:前后都取且连在一起
4:前后都取但分开

代码(写的有点诡异。。。):

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int inf=-1e9;int n,m,k;int f[105][11][5];int a[105][5];int main(){    scanf("%d%d%d",&n,&m,&k);    memset(f,192,sizeof(f));    memset(a,192,sizeof(a));    for (int i=1;i<=n;i++){        for (int j=1;j<=m;j++)            scanf("%d",&a[i][j]);        a[i][4]=a[i][3]=a[i][1]+a[i][2];    }    f[0][0][0]=0;    for (int i=1;i<=n;i++)        for (int p=0;p<=min(k,i*m);p++)            for (int j=0;j<=4;j++){                f[i][p][0]=max(f[i][p][0],f[i-1][p][j]);                if (p) f[i][p][1]=max(f[i][p][1],f[i-1][p-1][j]+a[i][1]);                if (p) f[i][p][2]=max(f[i][p][2],f[i-1][p-1][j]+a[i][2]);                if (p) f[i][p][3]=max(f[i][p][3],f[i-1][p-1][j]+a[i][3]);                if (p>1) f[i][p][4]=max(f[i][p][4],f[i-1][p-2][j]+a[i][4]);                if ((j==1||j==2)&&p) f[i][p][4]=max(f[i][p][4],f[i-1][p-1][j]+a[i][4]);                f[i][p][j]=max(f[i][p][j],f[i-1][p][j]+a[i][j]);                if (j==4){                    f[i][p][1]=max(f[i][p][1],f[i-1][p][j]+a[i][1]);                    f[i][p][2]=max(f[i][p][2],f[i-1][p][j]+a[i][2]);                }            }    int ans=-0x7fffffff;    for (int j=0;j<=4;j++)        ans=max(ans,f[n][k][j]);    printf("%d\n",ans);    return 0;}