[bzoj1084]最大子矩阵
用f[i][j][k]表示第一行前i个数,第二行前j个数选k个子矩形的答案,考虑转移:
1.在第一行/第二行选择一个矩形
2.当i=j时,可以选择一个两行的矩形
注意要特判m=1的情况
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,t,a[105][3],f[105][15],dp[105][105][15]; 4 int main(){ 5 scanf("%d%d%d",&n,&m,&t); 6 for(int i=1;i<=n;i++) 7 for(int j=1;j<=m;j++){ 8 scanf("%d",&a[i][j]); 9 a[i][j]+=a[i-1][j]; 10 } 11 if (m==1){ 12 for(int i=1;i<=n;i++) 13 for(int j=1;j<=t;j++){ 14 f[i][j]=f[i-1][j]; 15 for(int k=0;k<i;k++)f[i][j]=max(f[i][j],f[k][j-1]+a[i][1]-a[k][1]); 16 } 17 printf("%d",f[n][t]); 18 return 0; 19 } 20 for(int i=1;i<=n;i++) 21 for(int j=1;j<=n;j++) 22 for(int k=1;k<=t;k++){ 23 dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k]); 24 for(int l=0;l<i;l++)dp[i][j][k]=max(dp[i][j][k],dp[l][j][k-1]+a[i][1]-a[l][1]); 25 for(int l=0;l<j;l++)dp[i][j][k]=max(dp[i][j][k],dp[i][l][k-1]+a[j][2]-a[l][2]); 26 if (i==j) 27 for(int l=0;l<i;l++) 28 dp[i][j][k]=max(dp[i][j][k],dp[l][l][k-1]+a[i][1]-a[l][1]+a[i][2]-a[l][2]); 29 } 30 printf("%d",dp[n][n][t]); 31 }