[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 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11792808.html