zoukankan      html  css  js  c++  java
  • [ZJOI2006]超级麻将(动规)

    题目描述

    很多人都知道玩麻将,当然也有人不知道,呵呵,不要紧,我在这里简要地介绍一下麻将规则:

    普通麻将有砣、索、万三种类型的牌,每种牌有1~9个数字,其中相同的牌每个有四张,例如1砣~9砣,1索~9索,1万~9万各有4张,所以共36*3=108张牌。胡牌时每人有14张牌,其中只要某人手里有若干句话(就是同种类型的牌连续三张或同种牌三张),另外再加上一对,即可胡牌。当然如果全是对,叫七小对,也可以胡牌。下图是连三张示例。

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

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

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

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

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

    输入输出格式

    输入格式:

    输入文件第一行一个整数N(N<=100),表示玩了N次超级麻将。

    接下来N行,每行100个数a1..a100,描述每次玩牌手中各种牌的数量。ai表示数字为i的牌有ai张。(0<=ai<=100)

    输出格式:

    输出N行,若胡了则输出Yes,否则输出No,注意区分Yes,No的大小写!

    思路:

    HXY大神据说0msA题,Orz

    这道题我用了一种相当暴力的DP,卡过去了。。。

    我们开一个DP数组:dp[i][j][k][0/1]

    第一维表示在哪个位置,第二维表示前一个位置麻将还剩下几张,第三维表示现在位置还剩下几张,第四位表示当前是否走过对子

    dp数组的值表示这种情况能不能到达

    我们枚举位置,前一位要用掉多少,这一位要用掉多少,有没有用过对子

    转移即可

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define rii register int i
    #define rij register int j
    #define rik register int k 
    #define rit register int t
    using namespace std;
    int n,x[105],dp[105][105][105][2];
    int main()
    {
    //    freopen("1.in","r",stdin);
        scanf("%d",&n);
        for(rit=1;t<=n;t++)
        {
            memset(dp,0,sizeof(dp));
            for(rii=1;i<=100;i++)
            {
                scanf("%d",&x[i]);
            }
            dp[0][0][0][0]=1;
            for(rii=1;i<=100;i++)
            {
                for(rij=0;j<=x[i-1];j++)
                {
                    for(rik=0;k<=x[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(i-2<0&&k==0&&j>k)
                        {
                            dp[i][j][k][0]|=dp[i-1][0][j-k][0];
                            dp[i][j][k][1]|=dp[i-1][0][j-k][1];
                        }
                        if(j>=k&&x[i-2]>=k)
                        {
                            dp[i][j][k][0]|=dp[i-1][x[i-2]-k][j-k][0];
                            dp[i][j][k][1]|=dp[i-1][x[i-2]-k][j-k][1];
                        }
                    }
                }
            }
            if(dp[100][x[99]][x[100]][1]==1)
            {
                cout<<"Yes"<<endl;
            }
            else
            {
                cout<<"No"<<endl;
            }
        }
    }
  • 相关阅读:
    AUDIT审计的一些使用
    HOW TO PERFORM BLOCK MEDIA RECOVERY (BMR) WHEN BACKUPS ARE NOT TAKEN BY RMAN. (Doc ID 342972.1)
    使用BBED理解和修改Oracle数据块
    Using Class of Secure Transport (COST) to Restrict Instance Registration in Oracle RAC [ID 1340831.1]
    调试利器GDB概念
    第4章 思科IOS
    第3章 ip地址和子网划分
    第2章 TCPIP
    2020年阅读过的黑客资源推荐篇
    第1章 计算机网络
  • 原文地址:https://www.cnblogs.com/ztz11/p/9369790.html
Copyright © 2011-2022 走看看