BZOJ 1084 最大子矩阵

Posted on 2016-11-01 20:15  ziliuziliu  阅读(47)  评论(0编辑  收藏

奇怪的dp。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 2000000000
using namespace std;
int n,m,p,map[105][3],f[105][15],sum[105][3],dp[105][105][15],ans=-inf;
void work1()
{
    for (int i=1;i<=n;i++) scanf("%d",&map[i][1]);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=p;j++)
            f[i][j]=-inf;
    f[1][1]=map[1][1];
    for (int i=2;i<=n;i++)
    {
        for (int j=1;j<=p;j++)
        {
            for (int k=1;k<=i-2;k++)
                f[i][j]=max(f[i][j],f[k][j-1]);
            f[i][j]=max(f[i][j],f[i-1][j]);f[i][j]+=map[i][1];
        }
        ans=max(ans,f[i][p]);
    }
    printf("%d\n",ans);
}
void work2()
{
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            scanf("%d",&map[i][j]);
    for (int i=1;i<=n;i++)
    {
        sum[i][1]=sum[i-1][1]+map[i][1];
        sum[i][2]=sum[i-1][2]+map[i][2];
    }
    for (int i=0;i<=n;i++)
        for (int j=0;j<=n;j++)
            for (int k=1;k<=p;k++)
                dp[i][j][k]=-inf;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            for (int k=1;k<=p;k++)
            {
                dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k]);
                for (int l=0;l<=i-1;l++) dp[i][j][k]=max(dp[i][j][k],dp[l][j][k-1]+sum[i][1]-sum[l][1]);
                for (int l=0;l<=j-1;l++) dp[i][j][k]=max(dp[i][j][k],dp[i][l][k-1]+sum[j][2]-sum[l][2]);
                if (i==j)
                {
                    for (int l=0;l<=i-1;l++)
                        dp[i][j][k]=max(dp[i][j][k],dp[l][l][k-1]+sum[i][1]+sum[i][2]-sum[l][1]-sum[l][2]);
                }
            }
    printf("%d\n",dp[n][n][p]);
}
int main()
{
    scanf("%d%d%d",&n,&m,&p);
    if (m==1) work1();
    else work2();
    return 0;
}