• uva10559 Blocks(DP 费用提前)


    该题的难点在于费用的计算,需考虑未来能转移到的所有状态

    用dp[l][r][next]表示l到r之间以及r之后与r同色的所有next个方块的最大费用和

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int t,n,a[202],k,cnt;
    int dp[202][202][202];
    struct block{
        int x,c;
        block(){}
        block(int x,int c):x(x),c(c){}
    }b[202];
    void init(){
        k=1,cnt=1;
        for(int i=1;i<n;i++){
            if(a[i]==a[i-1]) cnt++;
            else{
                b[k++]=block(cnt,a[i-1]);
                cnt=1;
            }
        }
        b[k++]=block(cnt,a[n-1]);
    }
    int DP(int l,int r,int next){
        if(l>=r) return next*next;
        if(dp[l][r][next]!=-1) return dp[l][r][next];
        int ret=DP(l,r-1,b[r-1].x)+next*next;
        for(int i=r-1;i>=l;i--){
            if(b[i].c==b[r].c){
                ret=max(ret,DP(l,i,next+b[i].x)+DP(i+1,r-1,b[r-1].x));
            }
        }
        //cout<<l<<" "<<r<<" "<<next<<" "<<ret<<endl;
        return dp[l][r][next]=ret;
    }
    int gao(){
        memset(dp,-1,sizeof dp);
        return DP(1,k-1,b[k-1].x);
    }
    int main(){
        scanf("%d",&t);
        for(int ca=1;ca<=t;ca++){
            scanf("%d",&n);
            for(int i=0;i<n;i++) scanf("%d",&a[i]);
            init();
            printf("Case %d: %d
    ",ca,gao());
        }
        return 0;
    }
    uva10559
  • 相关阅读:
    ZIP压缩算法详细分析及解压实例解释
    nyoj 269 VF
    骨牌覆盖问题 KxM
    骨牌覆盖问题
    省赛总结...
    归并排序求逆序对
    「JLOI2014」松鼠的新家
    「JSOI2011」任务调度
    「JSOI2010」找零钱的洁癖
    「JSOI2011」棒棒糖
  • 原文地址:https://www.cnblogs.com/wonderzy/p/3540671.html
Copyright © 2020-2023  润新知