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
一维的方程很简单f[i][j]=max(f[k][j-1]+sum[i]-sum[k]);k<i
二维的需要考虑组成的并不是一个矩形的情况 令f[i][j][k]为第一行进行到i 第二行进行到j 分了k段的最大值
则有f[i][j][k]=max(f[l][j][k-1]+sum[1][i]-sum[1][l],f[j][l][k-1]+sum[2][j]-sum[2][l])
如果i==j那么还可以从f[l][l][k-1]+sum[1][i]-sum[1][l]+sum[2][j]-sum[2][l]转移过来
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int sum[110][3];
int f[110][20];
int A[110][3];
int g[110][110][20];
int main(){
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
int n,m,k;
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]);
//for(int i=1;i<=n;i++)
// printf("%d %d\n",A[i][1],A[i][2]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
sum[i][j]=sum[i-1][j]+A[i][j];
if(m==1){
for(int i=1;i<=n;i++){
for(int l=1;l<=k;l++){
for(int j=1;j<=i;j++)
f[i][l]=max(f[i][l],f[j-1][l-1]+sum[i][1]-sum[j-1][1]);
f[i][l]=max(f[i][l],f[i-1][l]);
}
}
printf("%d\n",f[n][k]);
}
else {
for(int l=1;l<=k;l++)
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
g[i][j][l]=max(g[i][j-1][l],g[i-1][j][l]);
for(int d=0;d<i;d++)
g[i][j][l]=max(g[i][j][l],g[d][j][l-1]+sum[i][1]-sum[d][1]);
for(int d=0;d<j;d++)
g[i][j][l]=max(g[i][j][l],g[i][d][l-1]+sum[j][2]-sum[d][2]);
if(i==j)
for(int d=0;d<i;d++)
g[i][j][l]=max(g[i][j][l],g[d][d][l-1]+sum[i][1]-sum[d][1]+sum[j][2]-sum[d][2]);
}
}
printf("%d\n",g[n][n][k]);
}
return 0;
}