zoukankan      html  css  js  c++  java
  • HDU 6212 Zuma(区间dp)

    Zuma

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 349    Accepted Submission(s): 95

    Problem Description
    Think about the Zuma Game. You have a row of at most 200 black(0) or white(1) balls on the table at the start. Each three consecutive balls never share the same colour. You also have infinite amount of black and white balls in your hand. On each turn, you can choose a ball in your hand and insert it into the row, including the leftmost place and the rightmost place. Then, if there is a group of three of more balls in the same colour touching, remove these balls. Keep doing this until no more balls can be removed.
    Find the minimal balls you have to insert to remove all the balls on the table.
    Input
    The first line of input contains an integer T (1T100) which is the total number of test cases.
    Each test case contains a line with a non-empty string of 0 and 1 describing the row of balls at the start.
    Output
    For each test case, output the case number and the minimal balls required to insert in a line.
    Sample Input
    4 10101 101001001 1001001001 01001101011001100
    Sample Output
    Case #1: 4 Case #2: 3 Case #3: 3 Case #4: 2
    Source
    【题意】给你一个01序列,你可以在任意位置加0或者1,没三个及其以上连续的0或者1在一起立马删去,问删完最少需要加入多少01.
    【分析】典型区间dp,我们先离散,记录每个连续0,1出现的个数,dp[l][r]表示消去区间[l,r]最少需要多少01,那么dp[l][r]我们可以通过     如下几种状态转移。
      如果l与r所在的数字相同,那么我们可以将中间部分删除完后再将他俩删除,比如11......11,此时我们可以将中间的省略号消去后,三     个1就碰到了一起,再消去;
      或者,从中间找到某个与两端数字相同的点,例如11......1......1,我们可以先将右边的省略号消去,就成了11......11,然后再将中间的     省略号消去,四个1 一起消去。
      但是这种转移要注意的是,这个游戏是有先后顺序的,如果你找的中间点k,他的个数是2的话,例如11......11......1,你无论先消去哪     个省略号,中间的11总会提前消去,
      就不能等5个一起消去了,而且两边不能同时为两个,同样的道理,这是遵守游戏规则。
      然后对于一般情况,都可以将区间分为两部分来消除,详情见代码。
      
    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define met(a,b) memset(a,b,sizeof a)
    #define pb push_back
    #define mp make_pair
    #define rep(i,l,r) for(int i=(l);i<=(r);++i)
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int N = 2e2+50;;
    const int M = 255;
    const int mod = 19260817;
    const int mo=123;
    const double pi= acos(-1.0);
    typedef pair<int,int>pii;
    int n,cas;
    char str[N];
    int dp[N][N];
    int a[N],cnt[N];
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            scanf("%s",str);printf("Case #%d: ",++cas);
            n=0;
            met(dp,inf);
            int c=0,pre=str[0]-'0';
            for(int i=0;i<strlen(str);i++,c++){
                if(str[i]-'0'!=pre){
                    cnt[++n]=c;
                    a[n]=pre;
                    c=0;pre=str[i]-'0';
                }
            }
            cnt[++n]=c;
            a[n]=pre;
            for(int i=1;i<=n;i++)dp[i][i]=(cnt[i]==1?2:1);
            for(int len=2;len<=n;len++){
                for(int l=1;l+len-1<=n;l++){
                    int r=l+len-1;
                    if(a[l]==a[r]){
                        dp[l][r]=min(dp[l][r],dp[l+1][r-1]+(cnt[l]+cnt[r]>=3?0:1));
                        if(cnt[l]+cnt[r]<=3){
                            for(int k=l+2;k<=r-2;k+=2){
                                if(cnt[k]==1)dp[l][r]=min(dp[l][r],dp[l+1][k-1]+dp[k+1][r-1]);
                            }
                        }
                    }
                    for(int k=l;k<r;k++)dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]);
                }
            }
            printf("%d
    ",dp[1][n]);
        }
        return 0;
    }
      
  • 相关阅读:
    有关怎样入门ACM
    在线安装eclipse中html/jsp/xml editor插件(很可靠)
    如何才干高速成为优秀的程序猿
    JavaScript必知的特性(继承)
    Maven构建真正的J2EE项目
    HLJU 1223: 寻找区间和 (交替推进法)
    重要经验五:block作为属性的注意事项
    Android Studio第一次启动的Fetching android sdk component information的问题
    树莓派学习笔记——apt方式安装opencv
    大型项目开发: 隔离 (《大规模C++程序设计》书摘)
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/7551794.html
Copyright © 2011-2022 走看看