1084: [SCOI2005]最大子矩阵

来源:互联网 发布:李晨璐 数据 编辑:程序博客网 时间:2024/06/05 09:06

题目链接

题目大意:这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵
不能相互重叠。

题解:开始没看见m<=2……
因为m只能取1/2,明显分类讨论

m=1
f[i][j]ijf[i][j]=f[i1][j]
p+1if[i][j]=max(f[p][j1]+s[i]s[p])

m=2
f[i][j][k]ijk

i=j,f[i][j][k]=max(f[p][p][k1]+s1[i]s1[p]+s2[j]s2[p])

我的收获:情况少->分类讨论

#include <iostream>#include <cstring>#include <cstdio>using namespace std;#define M 105int n,m,k;int a[M][M],s[M],g[M][M];int s1[M],s2[M],f[M][M][M];void solve1(){    for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i][1];    for(int i=1;i<=n;i++)        for(int j=1;j<=k;j++){            g[i][j]=g[i-1][j];            for(int p=0;p<i;p++)//start with 0                 g[i][j]=max(g[i][j],g[p][j-1]+s[i]-s[p]);        }    printf("%d\n",g[n][k]);}void solve2(){    for(int i=1;i<=n;i++) s1[i]=s1[i-1]+a[i][1],s2[i]=s2[i-1]+a[i][2];    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)            for(int l=1;l<=k;l++){                int &now=f[i][j][l];                now=max(f[i-1][j][l],f[i][j-1][l]);                for(int p=0;p<i;p++) now=max(now,f[p][j][l-1]+s1[i]-s1[p]);                for(int p=0;p<j;p++) now=max(now,f[i][p][l-1]+s2[j]-s2[p]);                if(i==j) for(int p=0;p<i;p++) now=max(now,f[p][p][l-1]+s1[i]-s1[p]+s2[j]-s2[p]);            }    printf("%d\n",f[n][n][k]);}void init(){    cin>>n>>m>>k;    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            scanf("%d",&a[i][j]);    if(m==1) solve1();    else solve2();}int main(){    init();    return 0;}
原创粉丝点击