题意

5E26 扑克牌 0x5E「动态规划」练习

描述

一副不含王的扑克牌由52张牌组成,由红桃、黑桃、梅花、方块4组牌组成,每组13张不同的面值。现在给定52

张牌中的若干张,请计算将它们排成一列,相邻的牌面值不同的方案数。

牌的表示方法为XY,其中X为面值,为2、3、4、5、6、7、8、9、T、J、Q、K、A中的一个。Y为花色,为S、

H、D、C中的一个。如2S、2H、TD等。

输入格式

第一行为一个整数T,为数据组数。

之后每组数据占一行。这一行首先包含一个整数N,表示给定的牌的张数,接下来N个由空格分隔的字符串,每个字符串长度为2,表示一张牌。每组数据中的扑克牌各不相同。

输出格式

对于每组数据输出一行,形如"Case #X: Y"。X为数据组数,从1开始。Y为可能的方案数,由于答案可能很大,

请输出模2^64之后的值。

样例输入

5
1 TC
2 TC TS
5 2C AD AC JC JH
4 AC KC QC JC
6 AC AD AS JC JD KD

样例输出

Case #1: 1
Case #2: 0
Case #3: 48
Case #4: 24
Case #5: 120

数据范围与约定

  • 1 ≤ T ≤ 20000,1 ≤ N ≤ 52
        </article>

分析

由于相同种类的牌的牌数只有1-4,而方案数容斥跟牌数相关,所以考虑以牌数建立状态。设\(F[a][b][c][d]\),表示1张的有a种,2张的有b种,3张的有c种,4张的有d种。

考虑如何容斥。首先如果放的是1张牌的,就只有a种方案。当牌数大于1时,用一个决策后的状态计算,要减去它转移到的不合法的状态。

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef unsigned long long ull;
co int N=20;
int n,num[N],c[N];
ull f[N][N][N][N];
char s[N];
ull dp(int a,int b,int c,int d){
if(f[a][b][c][d]!=-1LLU) return f[a][b][c][d];
ull ans=0;
if(a>0) ans+=(ull)a*dp(a-1,b,c,d);
if(b>0) ans+=(ull)b*2*(dp(a+1,b-1,c,d)-dp(a,b-1,c,d));
if(c>0) ans+=(ull)c*3*(dp(a,b+1,c-1,d)-2*(dp(a+1,b,c-1,d)-dp(a,b,c-1,d)));
if(d>0) ans+=(ull)d*4*(dp(a,b,c+1,d-1)-3*(dp(a,b+1,c,d-1)-2*(dp(a+1,b,c,d-1)-dp(a,b,c,d-1))));
return f[a][b][c][d]=ans;
}
int work(char c){
switch (c){
case 'T': return 10;
case 'J': return 11;
case 'Q': return 12;
case 'K': return 13;
case 'A': return 1;
default: return c-'0';
}
}
void Poker(int t){
read(n);
memset(num,0,sizeof num);
memset(c,0,sizeof c);
for(int i=1;i<=n;++i)
scanf("%s",s+1),++num[work(s[1])];
for(int i=1;i<=13;++i) ++c[num[i]];
printf("Case #%d: %llu\n",t,dp(c[1],c[2],c[3],c[4]));
}
int main(){
memset(f,-1,sizeof f);
f[0][0][0][0]=1;
for(int T=read<int>(),t=1;t<=T;++t) Poker(t);
return 0;
}

CH5E26 扑克牌的更多相关文章

  1. CH5E26 扑克牌 (计数类DP)

    $ CH~5E26~\times ~ $ 扑克牌: (计数类DP) $ solution: $ 唉,计数类DP总是这么有套路,就是想不到. 这道题我们首先可以发现牌的花色没有价值,只需要知道每种牌有 ...

  2. SCNU 2015ACM新生赛初赛【1007. ZLM的扑克牌】解题报告

            题目链接详见SCNU 2015新生网络赛 1007. ZLM的扑克牌 .         其实我在想这题的时候,还想过要不要设置求最小的排列,并且对于回文数字的话,可以把扑克牌折起来( ...

  3. Java 用LinkdeList实现52张扑克牌

    用LinkdeList实现52张扑克牌(不含大小王)的洗牌功能.提示:花色 ,和数字分别用数组存储. import java.util.LinkedList; import java.util.Ran ...

  4. C算法编程题(一)扑克牌发牌

    前言 上周写<我的编程开始(C)>这篇文章的时候,说过有时间的话会写些算法编程的题目,可能是这两天周末过的太舒适了,忘记写了.下班了,还没回去,闲来无事就写下吧. 因为写C++的编程题和其 ...

  5. JAVA collection集合之 扑克牌游戏

    主要内容:这里使用collection集合,模拟香港电影中大佬们玩的扑克牌游戏. 1.游戏规则:两个玩家每人手中发两张牌,进行比较.比较每个玩家手中牌最大的点数,大小由A-2,点数大者获胜.如果点数相 ...

  6. Java程序设计之扑克牌

    这段代码的主要实现功能扑克牌的洗牌和发牌功能,一副牌,红桃,黑桃,梅花,方片,A~K,不含大小王. 构造一个class. 首先是声明花色: private String[] sign={"方 ...

  7. js运动框架之掉落的扑克牌(重心、弹起效果)

    玩过电脑自带纸牌游戏的同志们应该都知道,游戏过关后扑克牌会依次从上空掉落,落下后又弹起,直至"滚出"屏幕. 效果如图:    这个案例的具体效果就是:点击开始运动,纸牌会从右上角掉 ...

  8. javascript练习-扑克牌

    下面用枚举类型来实现一副扑克牌的类: //定义一个玩牌的类 function Card(suit,rank){ function inherit(p){ if(p==null) throw TypeE ...

  9. JavaScript学习笔记-实现枚举类型,扑克牌应用

    //实现枚举类型,扑克牌应用 function creatEnum(p){     //构造函数     var Enumeration = function(){throw 'can not Ins ...

随机推荐

  1. 百练1724 ROADS

    总时间限制: 1000ms    内存限制: 65536kB 描述 N cities named with numbers 1 ... N are connected with one-way roa ...

  2. WordPress 设计学习

    "One can never be defeated until defeat has been accepted as a reality"----- Bruce Lee 官网免 ...

  3. java笔记4

    private关键字 1.是一个权限修饰符.       2.用于修饰成员       3.被私有化的成员只能在本类中有效 常用之一: -将成员变量私有化,对外提供对应的set,get方法对其进行访问 ...

  4. Python模拟知乎登录

    # -*- coding:utf-8 -*- import urllib import urllib2 import cookielib import time from PIL import Ima ...

  5. 贴一个markdown语法,mweb自带的说明

    Markdown 语法和 MWeb 写作使用说明 Markdown 的设计哲学 Markdown 的目標是實現「易讀易寫」.不過最需要強調的便是它的可讀性.一份使用 Markdown 格式撰寫的文件應 ...

  6. ElasticSerach 6.x的安装及配置

    1.准备工作 安装Centos7.建议内存2G以上.安装java1.8环境,固定IP地址,本文省略. 2.ElasticSerach单机安装 1) 创建/opt/es目录,存放文件ElasticSer ...

  7. Java线程之间通讯(三)

    使用wait和notify方法实现了线程间的通讯,都是Object 类的方法,java所有的对象都提供了这两个方法 1.wait和notify必须配合synchronized使用 2.wait方法释放 ...

  8. C#代码常用技巧

    1.拼sql语句时,list中元素加单引号并以逗号分开:string.Join(",",list.Select(r=>"'"+r+"'" ...

  9. NEST search查询

    /// <summary> /// GET /megacorp/employee/_search /// </summary> /// <returns></ ...

  10. 基于JMeter的Quick Easy FTP Server性能测试

    FTP性能测试 1.引言 1.1背景说明 本测试选用的是一个小型的FTP服务器软件:Quick Easy FTP Server.Quick Easy FTP Server是一个全中文的FTP服务器软件 ...