BZOJ1084_最大子矩阵_KEY

题目传送门

DP。

但要分类讨论,对于M=1和M=2的情况分别讨论。

1>M=1

  设f[i][j]表示选了i个矩阵,到第j位。N^3转移。(前缀和)

2>M=2

  设f[i][j][k]表示选了i个矩阵,第一列到i,第二列到j。

  枚举i,j,k后枚举j1和k1表示选一行的情况。

  如果j==k则可以从之前的两行一起转移。

code:

/**************************************************************
    Problem: 1084
    User: yekehe
    Language: C++
    Result: Accepted
    Time:112 ms
    Memory:1476 kb
****************************************************************/
 
#include <cstdio>   
#include <algorithm>   
using namespace std;   
       
int f[15][105][105];   
int N,M,K,a[105][3],sum[105][3];   
int F[15][105];   
int S[105];   
       
void work()   
{   
    for(int i=1;i<=N;i++){scanf("%d",&S[i]);S[i]+=S[i-1];}   
    for(int i=1;i<=K;i++)for(int j=1;j<=N;j++)F[i][j]=-1e9;   
    for(int i=1;i<=K;i++)   
        for(int j=1;j<=N;j++){   
            F[i][j]=F[i][j-1];   
            for(int k=0;k<j;k++){   
                F[i][j]=max(F[i][j],F[i-1][k]+S[j]-S[k]);   
            }   
        }   
    printf("%d",F[K][N]);   
    return ;   
}   
       
int main()   
{   
    scanf("%d%d%d",&N,&M,&K);   
    if(M==1)return work(),0;   
        for(int i=1;i<=N;i++)   
            for(int j=1;j<=M;j++){   
                scanf("%d",&a[i][j]);   
                sum[i][j]=sum[i-1][j]+a[i][j];   
            }   
        for(int i=1;i<=K;i++)for(int j=1;j<=N;j++)for(int k=1;k<=N;k++)f[i][j][k]=-1e9;   
        for(int i=1;i<=K;i++)   
            for(int j=1;j<=N;j++)   
                for(int k=1;k<=N;k++){   
                    f[i][j][k]=max(f[i][j-1][k],f[i][j][k-1]);   
                    for(int j1=0;j1<j;j1++)   
                        f[i][j][k]=max(f[i][j][k],f[i-1][j1][k]+sum[j][1]-sum[j1][1]);   
                    for(int k1=0;k1<k;k1++)   
                        f[i][j][k]=max(f[i][j][k],f[i-1][j][k1]+sum[k][2]-sum[k1][2]);   
                    if(j==k)   
                        for(int h=0;h<j;h++)   
                            f[i][j][k]=max(f[i][j][k],f[i-1][h][h]+sum[j][1]-sum[h][1]+sum[k][2]-sum[h][2]);   
                }   
    printf("%d",f[K][N][N]);   
    return 0;      
} 

 

posted @ 2018-04-02 13:52  Cptraser  阅读(45)  评论(0编辑  收藏