动态规划 BZOJ1084 [SCOI2005]最大子矩阵

来源:互联网 发布:ae软件怎么用 编辑:程序博客网 时间:2024/06/09 18:49

1084: [SCOI2005]最大子矩阵

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2771  Solved: 1379
[Submit][Status][Discuss]

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

HINT

 

Source

通读题目有时很重要,比如这个题……

发现可以根据m=1和m=2分类讨论地写,用前缀和容易想到,代码通俗易懂

 1 #include<iostream> 2 #include<cstdio>  3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int n,m,k,a; 7 int sum[110][3],f[110][12],g[110][110][12]; 8 int main(){ 9     scanf("%d%d%d",&n,&m,&k);10     for(int i=1;i<=n;i++)11         for(int j=1;j<=m;j++){12             scanf("%d",&a);13             sum[i][j]=sum[i-1][j]+a;    14         }15     if(m==1){16         for(int i=1;i<=n;i++)17             for(int j=1;j<=k;j++){18                 f[i][j]=f[i-1][j];19                 for(int p=0;p<=i-1;p++) f[i][j]=max(f[i][j],f[p][j-1]+sum[i][1]-sum[p][1]);20             }21         printf("%d\n",f[n][k]);22     }23     else{24         for(int i=1;i<=n;i++)25             for(int j=1;j<=n;j++)26                 for(int t=1;t<=k;t++){27                     g[i][j][t]=max(g[i-1][j][t],g[i][j-1][t]);28                     for(int p=0;p<=i-1;p++) g[i][j][t]=max(g[i][j][t],g[p][j][t-1]+sum[i][1]-sum[p][1]);29                     for(int p=0;p<=j-1;p++) g[i][j][t]=max(g[i][j][t],g[i][p][t-1]+sum[j][2]-sum[p][2]);30                     if(i==j)31                         for(int p=0;p<=i-1;p++) g[i][j][t]=max(g[i][j][t],g[p][p][t-1]+sum[i][1]-sum[p][1]+sum[i][2]-sum[p][2]); 32                 }33         printf("%d\n",g[n][n][k]);34     }35     return 0;36 }