bzoj1084: [SCOI2005]最大子矩阵
http://www.lydsy.com/JudgeOnline/problem.php?id=1084
m=1:
dp[i][j] 前i个数,选了j个矩阵的最大和
第i个不选:由dp[i-1][j]转移
第i个选:枚举i所在矩阵的左端点k,由dp[k][j-1]转移
m=2:
dp[i][j][k] 第1行前i个,第2行前j个,选了k个矩阵的最大和
2行都不选:dp[i-1][j-1][k]
只选第1行:枚举i所在矩阵的左端点h,由dp[h][j][k-1]转移
只选第2行:枚举j所在矩阵的左端点h,由dp[i][h][k-1]转移
如果i=j,2行都选:每局矩阵左端点h,由dp[h][h][k-1]转移
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 101 int n,m,k; int sum[2][N]; int DP[N][11],dp[N][N][11]; void read(int &x) { x=0; int f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } x*=f; } void init() { read(n); read(m); read(k); for(int i=1;i<=n;++i) for(int j=0;j<m;++j) { read(sum[j][i]); sum[j][i]+=sum[j][i-1]; } } void DP_() { for(int i=1;i<=n;++i) for(int j=1;j<=k;++j) { DP[i][j]=DP[i-1][j]; for(int h=0;h<i;++h) DP[i][j]=max(DP[i][j],DP[h][j-1]+sum[0][i]-sum[0][h]); } cout<<DP[n][k]; } void dp_() { for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) for(int h=1;h<=k;++h) { dp[i][j][h]=max(dp[i-1][j][h],dp[i][j-1][h]); for(int l=0;l<i;++l) dp[i][j][h]=max(dp[i][j][h],dp[l][j][h-1]+sum[0][i]-sum[0][l]); for(int l=0;l<j;++l) dp[i][j][h]=max(dp[i][j][h],dp[i][l][h-1]+sum[1][j]-sum[1][l]); if(i==j) for(int l=0;l<i;++l) dp[i][j][h]=max(dp[i][j][h],dp[l][l][h-1]+sum[0][i]-sum[0][l]+sum[1][j]-sum[1][l]); } cout<<dp[n][n][k]; } int main() { init(); if(m==1) DP_(); else dp_(); }
1084: [SCOI2005]最大子矩阵
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3296 Solved: 1641
[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