[bzoj1084][SCOI2005]最大子矩阵
呃本来今天是想写一下今天ditoly出的丧题的,但是没有包啊好尴尬,明天测一下再发吧。所以今天去bzoj水了一题充数。
---------------------------分割线
题意:给丁一个n*m的矩阵,最多选出k个不重叠子矩阵,求最大的元素和。n<=100,m<=2,k<=10
题解:没啥好说的啊m=1就是普及组水平dp吧??然后m=2多一维,f[k][i][j]表示第一行前i个,第二行前j个选出k个子矩阵的最大值。
复杂度n^3*k
#include<iostream> #include<cstdio> #define MAXN 100 using namespace std; 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 F[12][MAXN+5]; int f[12][MAXN+5][MAXN+5]; int n,m,K; int s[3][MAXN+5]; void solve1() { for(int k=1;k<=K;k++) for(int i=1;i<=n;i++) { F[k][i]=F[k][i-1]; for(int j=0;j<i;j++) F[k][i]=max(F[k][i],F[k-1][j]+s[1][i]-s[1][j]); } int ans=0; for(int i=0;i<=K;i++)ans=max(ans,F[i][n]); printf("%d\n",ans); } void solve2() { for(int i=1;i<=n;i++)s[0][i]=s[1][i]+s[2][i]; for(int k=1;k<=K;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { f[k][i][j]=max(f[k][i-1][j],f[k][i][j-1]); for(int l=0;l<i;l++) f[k][i][j]=max(f[k][i][j],f[k-1][l][j]+s[1][i]-s[1][l]); for(int l=0;l<j;l++) f[k][i][j]=max(f[k][i][j],f[k-1][i][l]+s[2][j]-s[2][l]); if(i==j) for(int l=0;l<i;l++) f[k][i][j]=max(f[k][i][j],f[k-1][l][l]+s[0][i]-s[0][l]); // cout<<k<<" "<<i<<" "<<j<<" "<<f[k][i][j]<<endl; } int ans=0; for(int i=0;i<=K;i++)ans=max(ans,f[i][n][n]); printf("%d\n",ans); } int main() { n=read();m=read();K=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) s[j][i]=read()+s[j][i-1]; if(m==1) solve1(); else solve2(); return 0; }
FallDream代表秋之国向您问好!
欢迎您来我的博客www.cnblogs.com/FallDream