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;
    }
  • 相关阅读:
    【转】busybox分析——arp设置ARP缓存表中的mac地址
    【转】OpenWRT开发自定义应用方法
    10大白帽黑客专用的 Linux 操作系统
    原始套接字
    正则表达式
    如何解决虚拟机中的ubuntu系统方向键与退格键不能正常使用的问题
    数组 slice方法和splice方法的区别
    数组去重等数组实例
    JS实现表单全选以及取消全选实例
    JS实现表格隔行变色
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9587967.html
Copyright © 2011-2022 走看看