bzoj1084 [SCOI2005]最大子矩阵(dp)
2017-08-04 14:12
435 查看
因为m<=2,就两种情况,所以分开做就好了。
1.m=1.那就是找k段连续和最大。dp[i][k]表示前i个数选k段的最大和。不选的话dp[i][k]=dp[i-1][k],选取j+1…i做为第k段的话,值为dp[j][k-1]+sum[1][i]-sum[1][j],取最大即可。
2.m=2.dp[i][j][k]表示第一列前i个,第二列前j个,一共选了k个矩阵。
(1)可以不选:
dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k]);
(2)可以在第一列选第k段:
dp[i][j][k]=max(dp[i][j][k],dp[ii][j][k-1]+sum[1][i]-sum[1][ii])
(3)可以在第二列选第k段:
dp[i][j][k]=max(dp[i][j][k],dp[i][jj][k-1]+sum[2][j]-sum[2][jj])
(4)如果i==j,还可以选择宽为2的矩阵作为第k个。
dp[i][j][k]=max(dp[i][j][k],dp[ii][ii][k-1]+sum[1][i]-sum[1][ii]+sum[2][j]-sum[2][ii])
取最大即可。
1.m=1.那就是找k段连续和最大。dp[i][k]表示前i个数选k段的最大和。不选的话dp[i][k]=dp[i-1][k],选取j+1…i做为第k段的话,值为dp[j][k-1]+sum[1][i]-sum[1][j],取最大即可。
2.m=2.dp[i][j][k]表示第一列前i个,第二列前j个,一共选了k个矩阵。
(1)可以不选:
dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k]);
(2)可以在第一列选第k段:
dp[i][j][k]=max(dp[i][j][k],dp[ii][j][k-1]+sum[1][i]-sum[1][ii])
(3)可以在第二列选第k段:
dp[i][j][k]=max(dp[i][j][k],dp[i][jj][k-1]+sum[2][j]-sum[2][jj])
(4)如果i==j,还可以选择宽为2的矩阵作为第k个。
dp[i][j][k]=max(dp[i][j][k],dp[ii][ii][k-1]+sum[1][i]-sum[1][ii]+sum[2][j]-sum[2][ii])
取最大即可。
#include <cstdio> #include <cstring> #define N 101 int n,m,K,sum[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; } inline int max(int x,int y){return x>y?x:y;} inline void solve1(){ int dp [11];memset(dp,0,sizeof(dp)); for(int k=1;k<=K;++k) for(int i=1;i<=n;++i){ dp[i][k]=dp[i-1][k]; for(int j=k-1;j<i;++j) dp[i][k]=max(dp[i][k],dp[j][k-1]+sum[1][i]-sum[1][j]); } printf("%d\n",dp [K]); } inline void solve2(){ int dp [11];memset(dp,0,sizeof(dp)); for(int k=1;k<=K;++k) for(int i=1;i<=n;++i) for(int j=1;j<=n;++j){ dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k]); for(int ii=0;ii<i;++ii) dp[i][j][k]=max(dp[i][j][k],dp[ii][j][k-1]+sum[1][i]-sum[1][ii]); for(int jj=0;jj<j;++jj) dp[i][j][k]=max(dp[i][j][k],dp[i][jj][k-1]+sum[2][j]-sum[2][jj]); if(i==j) for(int ii=0;ii<i;++ii) dp[i][j][k]=max(dp[i][j][k],dp[ii][ii][k-1]+sum[1][i]-sum[1][ii]+sum[2][j]-sum[2][ii]); } printf("%d\n",dp [K]); } int main(){ freopen("a.in","r",stdin); n=read();m=read();K=read(); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){int x=read();sum[j][i]=sum[j][i-1]+x;} if(m==1) solve1(); else solve2(); return 0; }
相关文章推荐
- bzoj 1084: [SCOI2005]最大子矩阵 (DP)
- 【BZOJ 1084】 [SCOI2005]最大子矩阵(DP)
- BZOJ 1084: [SCOI2005]最大子矩阵( dp )
- [DP] bzoj1084: [SCOI2005]最大子矩阵
- [BZOJ 1084] SCOI 2005 最大子矩阵 · 简单DP
- 【BZOJ 1084】 1084: [SCOI2005]最大子矩阵 (DP)
- bzoj1084: [SCOI2005]最大子矩阵(dp)
- [BZOJ1084][SCOI2005]最大子矩阵(dp)
- [bzoj1084][SCOI2005]最大子矩阵(DP)
- bzoj1084: [SCOI2005]最大子矩阵(Dp)
- 【BZOJ1084】【杂题DP】[SCOI2005]最大子矩阵 题解
- 【BZOJ】1084: [SCOI2005]最大子矩阵(DP)
- BZOJ 1084: [SCOI2005]最大子矩阵【DP】
- 洛谷P2331 [SCOI2005]最大子矩阵(BZOJ1084)
- BZOJ 1084: [SCOI2005]最大子矩阵
- 【BZOJ 1084】[SCOI2005]最大子矩阵
- 【BZOJ1084】[SCOI2005]最大子矩阵【DP】
- [BZOJ 1084] [SCOI2005] 最大子矩阵 【DP】
- bzoj1084: [SCOI2005]最大子矩阵
- [bzoj1084][SCOI2005]最大子矩阵_动态规划_伪·轮廓线dp