zoukankan      html  css  js  c++  java
  • 三维DP--POJ1390--Blocks

    题意介绍

    初看这道题,想了想没头绪,感觉又要被虐了,按照《算法基础》郭老师的讲解,勉强接受了这个奇怪的状态转移方程,但是还是感觉很吃力,照着视频写了一遍之后,又去网上看了看别人的代码,我的天哪,比郭老师的简洁多了!然后自己独立写了一遍,终于感觉好多了。原本感觉无从下手的难题,最后自己能够独立写出来,这种感觉真好,不过,能写出来不代表下一道状态转移方程如此之怪的题目我也能写,还是要多学习,多思考~

    最后想说的是,视频最后郭老师喝完水扔瓶子是真的骚

    言归正传:

    当遇到动归问题,我们的数学模型推不下去时,这道题其实给我们指明了方向:增加参数(维度),例如这道题就是三维动归

    初看这道题首先想到的估计大家都差不多(大神除外),那就是用前n-1个数字序列的结果算出前n个数字序列的结果,很快发现这样做是不行的,于是陷入了泥浆...终于想到了,我们可以用i--j-1之间的数字序列的结果去算推i--j之间的数字序列的结果,试了试发现好像也不行,于是陷入了泥浆...

    dp[L][R][K];

    其中K代表R右侧和R颜色一样的那一小排方块的数量,这样子dp[1][n][0]就是最终解,转态转移方程就也能写出来了(别问我怎么想到的,我也没想到):

    1.最右侧单独消除,dp[L][R][K]=dp[L][R-1][0]+(len[R]+k)^2;

    2.最右侧的,和区间段(L,R)中的某一块进行消除(要颜色一样能消除),假设iL< = p <  R满足条件,则dp[L][R][k]=dp[L][p][k+len[R]]+dp[p+1][R-1][0]。

     算出第一种的解,枚举所有第二种情况的解,取上面之中最大的结果即可,记得要记忆化搜索。

    代码:

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int maxn=200+50;
    
    int color[maxn],len[maxn];
    int ans[maxn][maxn][maxn];
    
    int dp(int l,int r,int k){
        int result,temp;
        if(ans[l][r][k]>0)
        return ans[l][r][k];
        result=k+len[r];
        result*=result;
        if(l==r){
            ans[l][r][k]=result;
            return result;
        }
        result+=dp(l,r-1,0);
        for(int i=r-1;i>=l;i--){
            if(color[i]!=color[r]) continue;
            temp=dp(l,i,len[r]+k)+dp(i+1,r-1,0);
            if(temp<result)
            continue;
            result=temp;
        }
        ans[l][r][k]=result;
        return result;
    }
    
    int main(){
    //    freopen("in.txt","r",stdin);
        int n,m,col,cnt;
        cin>>n;
        for(int i=0;i<n;i++){
            cin>>m;
            cin>>color[1];
            len[1]=1;
            cnt=1;
            for(int l=2;l<=m;l++){
                cin>>col;
                if(col==color[cnt])
                    len[cnt]++;
                else{
                    ++cnt;
                    color[cnt]=col;
                    len[cnt]=1;
                }
            }
            memset(ans,0,sizeof(ans));
            printf("Case %d: %d
    ",i+1,dp(1,cnt,0));
        }
    }
    柳暗花明又一村
  • 相关阅读:
    jmeter使用指南:jmeter无脑式指南
    手机上传图片的一些小问题
    总结-Linux
    阿里云服务器Linux CentOS安装配置(11)安装Wordpress
    Linux服务器tomcat启动很慢
    微信小程序开发的游戏《拼图游戏》
    微信小程序弹出操作菜单
    微信小程序计算经纬距离
    java.lang.NoClassDefFoundError: com/sun/image/codec/jpeg/JPEGCodec
    微信昵称有特殊符号怎么保存到mysql库里?
  • 原文地址:https://www.cnblogs.com/ucandoit/p/8502550.html
Copyright © 2011-2022 走看看