【BZOJ 1084】[SCOI2005]最大子矩阵
Description
这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。
Input
第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。
Output
只有一行为k个子矩阵分值之和最大为多少。
Sample Input
3 2 2
1 -3
2 3
-2 3
1 -3
2 3
-2 3
Sample Output
9
第一感觉状压,然后就写了,然后就30分了,不知道是压的不对还是什么,反正我没调出来
后来就改了一下状态f[i][j][k]表示第一行选到了i,第二行选到了j,共k块
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 int n,m,K,ans; 5 int f[110][110][15],s1[110],s2[110],a[110][5]; 6 int main(){ 7 scanf("%d%d%d",&n,&m,&K); 8 for(int i=1;i<=n;i++) 9 for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); 10 if(m==1){ 11 for(int i=1;i<=n;i++) s1[i]=s1[i-1]+a[i][1]; 12 for(int i=1;i<=n;i++) 13 for(int k=1;k<=K;k++){ 14 f[i][1][k]=f[i-1][1][k]; 15 for(int j=1;j<=i;j++){ 16 f[i][1][k]=max(f[i][1][k],f[j-1][1][k-1]+s1[i]-s1[j-1]); 17 } 18 } 19 printf("%d",f[n][1][K]); 20 }else{ 21 for(int i=1;i<=n;i++) 22 s1[i]=s1[i-1]+a[i][1], 23 s2[i]=s2[i-1]+a[i][2]; 24 for(int i=1;i<=n;i++) 25 for(int j=1;j<=n;j++) 26 for(int k=1;k<=K;k++){ 27 f[i][j][k]=max(f[i-1][j][k],f[i][j-1][k]); 28 for(int l=1;l<=i;l++) f[i][j][k]=max(f[i][j][k],f[l-1][j][k-1]+s1[i]-s1[l-1]); 29 for(int l=1;l<=j;l++) f[i][j][k]=max(f[i][j][k],f[i][l-1][k-1]+s2[j]-s2[l-1]); 30 if(i==j)for(int l=1;l<=i;l++){ 31 f[i][j][k]=max(f[i][j][k],f[l-1][l-1][k-1]+s2[j]-s2[l-1]+s1[i]-s1[l-1]); 32 } 33 } 34 printf("%d",f[n][n][K]); 35 } 36 }