bzoj1084【SCOI2005】最大子矩阵
1084: [SCOI2005]最大子矩阵
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1946 Solved: 970
[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
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #define F(i,j,n) for(int i=j;i<=n;i++) #define D(i,j,n) for(int i=j;i>=n;i--) #define ll long long #define inf 1000000000 using namespace std; int n,m,k; int f[105][15],g[105][105][15],s[105][3]; inline int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int main() { n=read();m=read();k=read(); memset(s,0,sizeof(s)); F(i,1,n) F(j,1,m) s[i][j]=s[i-1][j]+read(); if (m==1) { memset(f,0,sizeof(f)); F(i,1,n) F(j,1,k) { f[i][j]=f[i-1][j]; F(l,0,i-1) f[i][j]=max(f[i][j],f[l][j-1]+s[i][1]-s[l][1]); } printf("%d\n",f[n][k]); } else { memset(g,0,sizeof(g)); F(i,1,n) F(j,1,n) F(l,1,k) { g[i][j][l]=max(g[i-1][j][l],g[i][j-1][l]); F(h,0,i-1) g[i][j][l]=max(g[i][j][l],g[h][j][l-1]+s[i][1]-s[h][1]); F(h,0,j-1) g[i][j][l]=max(g[i][j][l],g[i][h][l-1]+s[j][2]-s[h][2]); if (i==j) F(h,0,i-1) g[i][j][l]=max(g[i][j][l],g[h][h][l-1]+s[i][1]-s[h][1]+s[j][2]-s[h][2]); } printf("%d\n",g[n][n][k]); } return 0; }