• UVA10059 Blocks 题解报告


    题目传送门

    【题目大意】

    有$n$个方块,每个方块有一个颜色。现在要消除这些方块,一段颜色相同的$k$个方块消除后的得分为$k^2$,求消除所有方块后的最大得分。

    【思路分析】

    这题还是很容易想到DP的?

    设$f[i][j][k]$表示当前处理到$[i,j]$,右边还有$k$个和$j$颜色相同的方块,我们考虑分情况转移:

    1.把$j$和后面$k$个同色方块一起消掉,$s[j]$表示$j$右边和$j$颜色相同的方块总数

    $$f[i][j][k]=max{f[i][j-1][0]+(k+1)^2}(kin[0,s[j]])$$

    2.在$[i,j]$之间找一个和$j$颜色相同的方块$p$,把$[p+1,j-1]$之间的方块消掉,然后把$p$和$j$以及$j$后面的$k$个颜色相同的方块一起消掉,$c[j]$代表$j$的颜色

    $$f[i][j][k]=max{f[i][p][k+1]+f[p+1][j-1][0]}(kin[0,s[j]],pin[i,j-1]&&c[p]=c[j])$$

    然后就是要注意一下循环的顺序,一定是从后往前转移!!!因为如果从前往后转移即$i,j$从小到大枚举,那么在求$f[i][j][k]$的时候还没有求出$f[p+1][j-1][0]$的值,这样是错的!

    最后的答案是$f[1][n][0]$

    【代码实现】

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #define g() getchar()
     8 #define rg register
     9 #define go(i,a,b) for(rg int i=a;i<=b;i++)
    10 #define back(i,a,b) for(rg int i=a;i>=b;i--)
    11 #define db double
    12 #define ll long long
    13 #define il inline
    14 #define pf printf
    15 #define mem(a,b) memset(a,b,sizeof(a))
    16 using namespace std;
    17 int fr(){
    18     int w=0,q=1;
    19     char ch=g();
    20     while(ch<'0'||ch>'9'){
    21         if(ch=='-') q=-1;
    22         ch=g();
    23     }
    24     while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g();
    25     return w*q;
    26 }
    27 const int N=202;
    28 int T,n,c[N],s[N],f[N][N][N];
    29 int main(){
    30     //freopen("","r",stdin);
    31     //freopen("","w",stdout);
    32     T=fr();
    33     go(t,1,T){
    34         n=fr();
    35         mem(f,0);mem(s,0);
    36         go(i,1,n) c[i]=fr();
    37         back(i,n-1,1) go(j,i+1,n) if(c[i]==c[j]) s[i]++;
    38         back(i,n,1) go(j,i,n){//i要从大到小枚举!
    39             go(p,i,j-1)
    40                 if(c[p]==c[j])
    41                     go(k,0,s[j]) f[i][j][k]=max(f[i][j][k],f[i][p][k+1]+f[p+1][j-1][0]);
    42             go(k,0,s[j]) f[i][j][k]=max(f[i][j][k],f[i][j-1][0]+(k+1)*(k+1));
    43         }
    44         pf("Case %d: %d
    ",t,f[1][n][0]);
    45     }
    46     return 0;
    47 }
    代码戳这里
  • 相关阅读:
    CentOS7突然出现无法连接网络的情况--VM下
    设置Linux系统的LANG变量
    习题
    Linux目录路径知识
    Linux目录详细介绍
    regexp正则
    https://github.com/rwson/awesome-javascript-cn
    JavaScript资源大全中文版(Awesome最新版)
    关于 Chrome DevTools 的 25 个实用技巧
    从前端菜鸟到大神,看这一篇就够了
  • 原文地址:https://www.cnblogs.com/THWZF/p/11588771.html
Copyright © 2020-2023  润新知