zoukankan      html  css  js  c++  java
  • SPOJ6340 ZUMA

    题意:n个珠子排成一排,都有各自的颜色。

    你可以选择不少于w个连续同色的珠子消掉,也可以先放着。你还可以任意插入任意颜色的珠子。

    求全部消掉至少要插入几个珠子。

    解:

    什么毒瘤东西......

    有个十分难受的DP。状态表示是f[l][r][k]表示在[l, r]这一段,l的左边有额外的k个与l同色的珠子时,把它们全部消去的最少代价。

    转移也过于毒瘤。首先有

    if k == w - 1
      f[l][r][k] = f[l + 1][r][0] 
    else
        f[l][r][k] = f[l][r][k + 1] + 1

    然后然后还要考虑两段拼起来的情况,就是我们从中间选一段消去。

    if(color i == l) 
        f[l][r][k] = f[l + 1][i - 1][0] + f[i][r][k + 1] 

    这样我们就可以保证正确性了。写成记忆化搜索不用考虑转移顺序。代码十分之短.....

    需要注意的是不能把相连的一段同色珠子合并,这样不一定是最优解。(??)

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 const int N = 110, INF = 0x3f3f3f3f;
     6 
     7 int f[N][N][N], n, a[N], w; 
     8 int sum[N], col[N], top;
     9 
    10 int solve(int l, int r, int k) {
    11     //printf("%d %d %d 
    ", l, r, k);
    12     if(f[l][r][k] != -1) {
    13         return f[l][r][k];
    14     }
    15     if(r < l) {
    16         return 0;
    17     }
    18     
    19     int ans = INF;
    20     if(k + 1 >= w) {
    21         ans = solve(l + 1, r, 0);
    22     }
    23     else {
    24         ans = solve(l, r, k + 1) + 1;
    25     }
    26     for(int i = l + 1; i <= r; i++) { 
    27         if(col[l] == col[i]) { // [l + 1, i - 1]  [i, r] 
    28             ans = std::min(ans, solve(l + 1, i - 1, 0) + solve(i, r, k + 1)); 
    29         }
    30     }
    31     return f[l][r][k] = ans;
    32 }
    33 
    34 int main() {
    35     memset(f, -1, sizeof(f));
    36     scanf("%d%d", &n, &w);
    37     for(int i = 1; i <= n; i++) {
    38         scanf("%d", &col[i]);
    39     }
    40     
    41     int ans = solve(1, n, 0); 
    42     printf("%d", ans);
    43     
    44     return 0;
    45 }
    AC代码

    除此之外还有两种四维状态的DP,一种是f[l][r][k][a]表示把l到r这一段区间消除至只剩a(左/右)端的k个珠子的最小代价。

    还有一种是f[l][r][k][s]表示把l到r这一段区间消除至只剩k个s颜色的珠子的最小代价。

    写起来比较长,但是应该是比正解好想很多的。我没写,就不贴代码了。

  • 相关阅读:
    马云演讲:给自己一个梦想,给自己一个承诺,给自己一个坚持!
    转:如何成为一个伟大的开发者
    数据挖掘之七种常用的方法
    windows命令行
    100万亿意味着什么?
    ubuntu环境配置
    Ubuntu runlevel修改
    Ubuntu 用户及组管理
    Git学习笔记
    Git详解之三 Git分支
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/9887174.html
Copyright © 2011-2022 走看看