bzoj1084 [SCOI2005]最大子矩阵
2017-10-24 22:26
387 查看
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 21 -3
2 3
-2 3
Sample Output
9正解:$dp$。
首先注意到一个性质:$m\leq 2$。
那么我们可以考虑一下,每次一个子矩阵要么只在第一列,要么只在第二列,要么横跨两列。
那么我们可以设$f[i][j][k]$表示第一列到$i$,第二列到$j$,取了$k$个子矩阵的最大值,转移比较简单,不过注意第三种情况只有$i=j$时才能转移。
$m=1$时同理,就是把$f[i][j][k]$换成$f[i][k]$就行了。
#include <bits/stdc++.h> #define il inline #define RG register #define ll long long #define inf (1<<30) using namespace std; int sum[110][2],g[110][2],n,m,k; il int gi(){ RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; } namespace dp1{ int f[110][12]; int main(){ for (RG int i=0;i<=n;++i) for (RG int j=1;j<=k;++j) f[i][j]=-inf; for (RG int i=1;i<=n;++i) for (RG int j=1;j<=k;++j){ f[i][j]=max(f[i][j],f[i-1][j]); for (RG int p=0;p<i;++p) f[i][j]=max(f[i][j],f[p][j-1]+sum[i][1]-sum[p][1]); } cout<<f [k]; return 0; } } namespace dp2{ int f[110][110][12]; int main(){ for (RG int i=0;i<=n;++i) for (RG int j=0;j<=n;++j) for (RG int p=1;p<=k;++p) f[i][j][p]=-inf; for (RG int i=1;i<=n;++i) for (RG int j=1;j<=n;++j) for (RG int p=1;p<=k;++p){ f[i][j][p]=max(f[i][j][p],f[i-1][j][p]); f[i][j][p]=max(f[i][j][p],f[i][j-1][p]); for (RG int pre=0;pre<i;++pre) f[i][j][p]=max(f[i][j][p],f[pre][j][p-1]+sum[i][1]-sum[pre][1]); for (RG int pre=0;pre<j;++pre) f[i][j][p]=max(f[i][j][p],f[i][pre][p-1]+sum[j][2]-sum[pre][2]); if (i==j) for (RG int pre=0;pre<i;++pre) f[i][j][p]=max(f[i][j][p],f[pre][pre][p-1]+sum[i][1]-sum[pre][1]+sum[j][2]-sum[pre][2]); } cout<<f [k]; return 0; } } int main(){ #ifndef ONLINE_JUDGE freopen("matrix.in","r",stdin); freopen("matrix.out","w",stdout); #endif n=gi(),m=gi(),k=gi(); for (RG int i=1;i<=n;++i) for (RG int j=1;j<=m;++j) g[i][j]=gi(); for (RG int i=1;i<=n;++i){ sum[i][1]=sum[i-1][1]+g[i][1]; sum[i][2]=sum[i-1][2]+g[i][2]; } if (m==1) dp1::main(); if (m==2) dp2::main(); return 0; }
相关文章推荐
- bzoj 1084: [SCOI2005]最大子矩阵
- bzoj1084: [SCOI2005]最大子矩阵(dp)
- bzoj1084: [SCOI2005]最大子矩阵
- [bzoj1084][SCOI2005]最大子矩阵(DP)
- 【BZOJ】1084: [SCOI2005]最大子矩阵(DP)
- [DP] bzoj1084: [SCOI2005]最大子矩阵
- BZOJ1084: [SCOI2005]最大子矩阵
- BZOJ1084: [SCOI2005]最大子矩阵
- BZOJ1084: [SCOI2005]最大子矩阵
- [bzoj1084][SCOI2005]最大子矩阵
- 【BZOJ 1084】 [SCOI2005]最大子矩阵
- [BZOJ1084] [SCOI2005]最大子矩阵
- bzoj1084[SCOI2005]最大子矩阵
- 【BZOJ 1084】 1084: [SCOI2005]最大子矩阵 (DP)
- BZOJ1084 [SCOI2005]最大子矩阵
- bzoj 1084: [SCOI2005]最大子矩阵 题解
- BZOJ1084 [SCOI2005] 最大子矩阵
- BZOJ1084 SCOI2005最大子矩阵
- BZOJ_1084_[SCOI2005]_最大子矩阵_(动态规划)
- bzoj1084【SCOI2005】最大子矩阵