bzoj 1084

由于m只会是1或者2,那么就干脆分类讨论,可以开两个namespace实现。

当m为1时。

设dp[i][j]表示前i个数中选了j个矩阵的最大值。

dp[i][j]=max(dp[i-1][j],dp[k][j-1]+sum[i]-sum[k])(0<=k<i)。

当m为2时。

设dp[i][j][k]表示第一列前i个,第2列前j个中选了k个矩阵的最大值。

dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k])

dp[i][j][k]=max(dp[h][j][k-1]+sum[i][0]-sum[h][0],dp[i][j][k])(0<=h<i)

dp[i][j][k]=max(dp[i][h][k-1]+sum[j][1]-sum[h][1],dp[i][j][k])(0<=h<j)

dp[i][j][k]=max(dp[h][h][k-1]+sum[i][0]-sum[h][0]+sum[j][1]-sum[h][1],dp[i][j][k])(i=j,0<=h<i)]

貌似忘记赋值为-oo还是过了。

 

#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
#define k1 sum[i][0]-sum[h][0]
#define k2 sum[j][1]-sum[h][1]
int read(){
    char c; while(!isdigit(c=getchar()) && c!='-');
    int x=0,y=1; if(c=='-') y=-1; else x=c-'0';
    while(isdigit(c=getchar())) x=x*10+c-'0'; return x*y;
}
namespace f1{
    int dp[101][11],sum[101];
    void work(int n,int c){
        for(int i=1;i<=n;i+=1) sum[i]=sum[i-1]+read();
        for(int i=1;i<=n;i+=1)
            for(int k=1;k<=c;k+=1) dp[i][k]=-2e9;
        for(int i=1;i<=n;i+=1)
            for(int j=1;j<=c;j+=1){
                dp[i][j]=dp[i-1][j];
                for(int k=i-1;k>=0;k-=1)
                    dp[i][j]=max(dp[k][j-1]+sum[i]-sum[k],dp[i][j]);
            }
        printf("%d",dp[n][c]);
    }
};
namespace f2{
    int dp[101][101][11],sum[101][2];
    void work(int n,int c){
        for(int i=1;i<=n;i+=1)
            for(int j=0;j<2;j+=1)
                sum[i][j]=sum[i-1][j]+read();
        for(int i=0;i<=n;i+=1)
            for(int j=0;j<=n;j+=1)
                for(int k=1;k<=c;k+=1) dp[i][j][k]=-2e9;
        for(int i=1;i<=n;i+=1)
            for(int j=1;j<=n;j+=1)
                for(int k=1;k<=c;k+=1){
                    dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k]);
                    for(int h=0;h<i;h+=1)
                        dp[i][j][k]=max(dp[h][j][k-1]+k1,dp[i][j][k]);
                    for(int h=0;h<j;h+=1)
                        dp[i][j][k]=max(dp[i][h][k-1]+k2,dp[i][j][k]);
                    if(i==j)
                        for(int h=0;h<i;h+=1)
                            dp[i][j][k]=max(dp[h][h][k-1]+k1+k2,dp[i][j][k]);
                }
        printf("%d",dp[n][n][c]);
    }
};
int main(){
    int n=read(),m=read(),c=read();
    if(m==1) f1::work(n,c);
    else f2::work(n,c);
    return 0;
}

 

posted @ 2017-10-23 17:46  或是七一  阅读(50)  评论(0编辑  收藏