zoukankan      html  css  js  c++  java
  • [ZJOI2006]超级麻将(可行性dp)

    题目描述

    要判断某人是否胡牌,显然一个弱智的算法就行了,某中学信息学小组超级麻将迷想了想,决定将普通麻将改造成超级麻将。

    所谓超级麻将没有了砣、索、万的区分,每种牌上的数字可以是1~100,而每种数字的牌各有100张。另外特别自由的是,玩牌的人手里想拿多少张牌都可以,好刺激哦!

    刺激归刺激,但是拿多了怎么胡牌呢?

    超级麻将规定只要一个人手里拿的牌是若干句话(三个连续数字的牌各一张组成一句话,三张或者四张同样数字的牌也算一句话),再加上一对相同的牌,就算胡了。

    作为信息学竞赛选手的你,麻烦你给这位超级麻将迷编个程序,判断能否胡牌。

    Solution

    可行性dp,设dp[i][j][k][0/1]为到第i个,当前用了k个,上一次用j个,出没出对子,能否可行。

    转移:

    出顺,则必须保证dp[i-1][a[i-2]-k][j-k][0/1]。

    然后讨论一下出对,三个的,四个的,同层转移,

    Code

    #include<iostream>
    #include<cstdio>
    #include<bitset>
    #include<cstring>
    using namespace std;
    bool dp[101][101][101][2];
    int t,b[10],a[102];
    int rd(){
        int x=0;char c=getchar();
        while(!isdigit(c))c=getchar();
        while(isdigit(c)){
            x=(x<<1)+(x<<3)+(c^48);
            c=getchar();
        }
        return x;
    }
    int main(){
        t=rd();
        while(t--){
            memset(dp,0,sizeof(dp));dp[0][0][0][0]=1;
            for(int i=1;i<=100;++i){
              a[i]=rd(); 
              for(int j=0;j<=a[i-1];++j)
                for(int k=0;k<=a[i];++k){
                    if(k>1)dp[i][j][k][1]|=dp[i][j][k-2][0];
                    if(k>2)dp[i][j][k][1]|=dp[i][j][k-3][1],dp[i][j][k][0]|=dp[i][j][k-3][0];
                    if(k>3)dp[i][j][k][1]|=dp[i][j][k-4][1],dp[i][j][k][0]|=dp[i][j][k-4][0];
                    if(j>=k&&a[i-2]>=k)dp[i][j][k][0]|=dp[i-1][a[i-2]-k][j-k][0],dp[i][j][k][1]|=dp[i-1][a[i-2]-k][j-k][1];
                }
             }
             printf(dp[100][a[99]][a[100]][1]?"Yes
    ":"No
    ");
        }
        return 0;
    }
  • 相关阅读:
    java代码--Date类获取当前时间-格式化输出
    Eclipse快速生成do while if 等方法
    java不同包中protected修饰的属性和方法调用方法
    java中如果删除导入的jar包,工程出现叹号解决方案
    Best Reward HDU 3613(回文子串Manacher)
    Teacher YYF
    Period II
    How many
    String Problem
    Corporate Identity
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9587967.html
Copyright © 2011-2022 走看看