1084: [SCOI2005]最大子矩阵
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3566 Solved: 1785
[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
1 -3
2 3
-2 3
Sample Output
9
HINT
Source
思路:
可以把m=1和m=2分开处理。
当m=1时,有:f[i][k]表示到前i个数为止,选k的子矩阵的最优解。
那么第i个数有选和不选两种情况
不选:f[i][k]=max(f[i][k],f[i-1][k]);
选:f[i][k]=max(f[i][k],f[q][k-1]+sum[i][1]-sum[q][1])
当m=2时,有:g[k][i][j]表示左列到前i个,右列到前j个数为止,选出k个子矩阵的最优解。
可先分开考虑,对于每一列有选和不选两种情况。
然后当i==j时,考虑两列同时选和不选两种情况。
有:
g[j][i1][i2]=max(g[j][i1-1][i2],g[j][i1][i2]);
g[j][i1][i2]=max(g[j][i1][i2-1],g[j][i1][i2]);
g[j][i1][i2]=max(g[j-1][q][i2]+sum[i1][1]-sum[q][1],g[j][i1][i2]);
g[j][i1][i2]=max(g[j-1][i1][q]+sum[i2][2]-sum[q][2],g[j][i1][i2]);
g[j][i1][i2]=max(g[j-1][q][q]+sum[i1][1]-sum[q][1]+sum[i2][2]-sum[q][2],g[j][i1][i2]);
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m,k; int sum[103][3]; int a[103][3],f[103][103],g[103][103][103]; int main(){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ scanf("%d",&a[i][j]); sum[i][j]=sum[i-1][j]+a[i][j]; } /*for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cout<<sum[i][j]<<" "; } cout<<endl; }*/ if(m==1){ for(int i=1;i<=n;i++){ for(int j=1;j<=k;j++){ f[i][j]=max(f[i-1][j],f[i][j]); for(int q=0;q<i;q++) f[i][j]=max(f[i][j],f[q][j-1]+sum[i][1]-sum[q][1]); } } cout<<f[n][k]; } else if(m==2){ for(int i1=1;i1<=n;i1++) for(int i2=1;i2<=n;i2++) for(int j=1;j<=k;j++){ g[j][i1][i2]=max(g[j][i1-1][i2],g[j][i1][i2]); g[j][i1][i2]=max(g[j][i1][i2-1],g[j][i1][i2]); for(int q=0;q<i1;q++) g[j][i1][i2]=max(g[j-1][q][i2]+sum[i1][1]-sum[q][1],g[j][i1][i2]); for(int q=0;q<i2;q++) g[j][i1][i2]=max(g[j-1][i1][q]+sum[i2][2]-sum[q][2],g[j][i1][i2]); if(i1==i2) for(int q=0;q<i1;q++) g[j][i1][i2]=max(g[j-1][q][q]+sum[i1][1]-sum[q][1]+sum[i2][2]-sum[q][2],g[j][i1][i2]); // cout<<g[j][i1][i2]<<"-->"; } cout<<g[k][n][n]; } } /* 3 2 2 1 -3 2 3 -2 3 */