zoukankan      html  css  js  c++  java
  • 动态规划7--方盒游戏

    动态规划7--方盒游戏

    一、心得

    直接根据问题写状态
    如果不能写出状态转移方程,就多维(细化),直至能够写出状态转移方程。

    二、题目和分析

    题意:
    N个方盒(box)摆成一排,每个方盒有自己的颜色。连续摆放的同颜色方盒构成
    一个方盒片段(box segment)。下图中共有四个方盒片段,每个方盒片段分别有
    1、4、3、1个方盒
    玩家每次点击一个方盒,则该方盒所在方盒片段就会消失。若消失的方盒片段

    中共有k个方盒,则玩家获得k*k个积分。

    思路:区间dp
    首先将每个连续颜色的盒子看成一个“块”
    click_box(i,j,exlen)代表从i到j以及exlen消除掉可以得到的最高分
    exlen表示j右边的“块”,这个块可能不是最初的块,可能是消掉一部分块后形成的
    且j的颜色和exlen相同
    目标状态: click_box(0,n-1,0)
    递推过程
    1.直接将j和exlen消除掉
    得到click_box(i,j-1,0) + (len[j]+exlen)^2
    2.不消除j和exlen,以待以后消除得到更高的分数,贪心啊哈,
    更新exlen为len[j]+exlen,假设又和k块颜色相同了(k在i和j之间)

    可以得到click_box(i,k,len[j]+exlen) + click_box(k+1,j-1,0)

    三、代码

    核心代码

     1 /*
     2 动态规划7--方盒游戏
     3 进一步细化之后(复杂化,多维化)
     4 click_box(i,j,ex_len)
     5 表示:
     6 大块j的右边已经有一个长度为ex_len的大块,且j的颜色和ex_len相同,
     7 在此情况下将i到j以及ex_len都消除所能得到的最高分
     8 初始状态: click_box(0,n-1,0)
     9 
    10 递推关系:
    11 求click_box(i,j,ex_len)时,有两种处理方法,取最优者,
    12 假设j与ex_len合并后的大块称作Q
    13 1)将Q直接消除,这种做法能得到的最高分就是:
    14 click_box(i,j-1,0)+(len[j]+ex_len)^2
    15 2) 期待Q以后能和左边的某个同色大块合并。需要枚举可能和W合并的大块。
    16 假设让大块k和W合并,则此时能得到的最大分数是:
    17 click_box(i,k,len[j]+ex_len)+click_box(k+1,j-1,0) 
    18 
    19 递归终止条件:
    20 i==j
    21  
    22 */
    23 #include <cstring>
    24 #include <iostream>
    25 using namespace std;
    26 struct Block{
    27     int color;
    28     int len;
    29 }; 
    30 struct Block segment[200];
    31 int score[200][200][200];//记忆化递归,存放计算结果,避免重复计算
    32 int click_box(int start,int end,int extra_len){
    33     //第一种情况  1)将Q直接消除,这种做法能得到的最高分就是:
    34     int i,result,temp;
    35     //如果score[start][end][extra_len]被计算过,就直接返回 
    36     if(score[start][end][extra_len]>0)
    37         return score[start][end][extra_len];
    38     result = segment[end].len+extra_len;//这个就是Q
    39     //将Q直接消除 
    40     result = result*result;//end和extra_len一起消去的得分
    41     //头和尾相同了,没得消除的了 
    42     if(start==end){//递归终止条件 
    43         score[start][end][extra_len]=result;
    44         return score[start][end][extra_len]; 
    45     } 
    46     result += click_box(start,end-1,0);
    47     
    48     //第一种情况 
    49     
    50     //------------------------------------------------------------------ 
    51     
    52     //第二种情况  2) 期待Q以后能和左边的某个同色大块合并。
    53     i=end-1;
    54     for(i=end-1;i>=start;i--){//从最后往前找和Q颜色相同的方盒 
    55         //如果方盒颜色不同,不能合并 
    56         if(segment[i].color!=segment[end].color)
    57             continue;
    58         //下面执行颜色相同的情况
    59         //也就是第二种情况 
    60         temp=click_box(start,i,segment[end].len+extra_len)+click_box(i+1,end-1,0);
    61         if(temp<=result) continue;
    62         //如果temp大,那么result变成temp 
    63         result=temp; 
    64     }
    65     
    66     //将第一种情况和第二种情况中的较大值返回 
    67     score[start][end][extra_len]=result;
    68     return score[start][end][extra_len]; 
    69 } 
  • 相关阅读:
    文件编码转换
    mysql密码的奇怪问题
    python文件读写
    python中JSON的使用
    mysql默认字符编码的修改
    烧写uboot与linux操作系统,安装Samba,jlink驱动安装
    Busybox是什么?
    ubuntu 搭建GTK+以及glade2集成开发环境的一些方法
    Ubuntu linux安装ssh server
    UBoot启动过程(国嵌)
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7057293.html
Copyright © 2011-2022 走看看