【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

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 } 

 

你可能感兴趣的:(【BZOJ 1084】[SCOI2005]最大子矩阵)