【bzoj1084】最大子矩阵
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
Solution
我们发现,这个矩阵惊人的只有两行
一行的话,应当是很显然的
f[i][j]代表1~i取了j段,暴力转移即可
两行的话
f[i][j][k]第一行前i个,第二行前j个,共取了k段
暴力枚举这一段有多长即可
#include<stdio.h> #include<stdlib.h> #include<iostream> #include<string> #include<string.h> #include<algorithm> #include<math.h> #include<queue> #include<map> #include<vector> #include<set> #define il inline #define re register #define inf 1000000000 using namespace std; int n,m,a[101],b[101],p,g[101][101],f[101][101][101]; int main(){ scanf("%d%d%d",&n,&m,&p); if(m==1){ for(int i=1,x;i<=n;i++){ scanf("%d",&x); a[i]=a[i-1]+x; } for(int i=1;i<=n;i++){ for(int j=1;j<=p;j++){ g[i][j]=g[i-1][j]; for(int k=0;k<i;k++) g[i][j]=max(g[i][j],g[k][j-1]+a[i]-a[k]); } } cout<<g[n][p];return 0; } for(int i=1,x,y;i<=n;i++){ scanf("%d%d",&x,&y); a[i]=a[i-1]+x; b[i]=b[i-1]+y; } for(int k=1;k<=p;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ f[i][j][k]=max(f[i-1][j][k],f[i][j-1][k]); for(int l=0;l<i;l++) f[i][j][k]=max(f[l][j][k-1]+a[i]-a[l],f[i][j][k]); for(int l=0;l<j;l++) f[i][j][k]=max(f[i][l][k-1]+b[j]-b[l],f[i][j][k]); if(i==j){ for(int l=0;l<i;l++) f[i][j][k]=max(f[i][j][k],f[l][l][k-1]+a[i]-a[l]+b[j]-b[l]); } } cout<<f[n][n][p]<<endl; return 0; }
蜉蝣渴望着飞翔,尽管黄昏将至