博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hihoCoder #1159 : 扑克牌
阅读量:5884 次
发布时间:2019-06-19

本文共 2777 字,大约阅读时间需要 9 分钟。

 

描述

一副不含王的扑克牌由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为可能的方案数,由于答案可能很大,请输出模264之后的值。

数据范围

1 ≤ T ≤ 20000

小数据

1 ≤ N ≤ 5

大数据

1 ≤ N ≤ 52

样例输入

51 TC2 TC TS5 2C AD AC JC JH4 AC KC QC JC6 AC AD AS JC JD KD

样例输出

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

题解:

  这个题目,首先我们把模型抽象出来,13种物品,每种物品最多会有4个,当然同种物品之间也会有区别,用n个物品排出一个序列,使得相邻的两个物品种类不相同。

  当然,这个题目模型一抽象出来,就十分眼熟,当然我们先不提那个题目,我们先看一下数据范围,每个物品最多只会有四种,那么我们显然可以按照物品的剩余数量给他们进行分类。

  我们设dp[a1][a2][a3][a4][last]表示剩余物品数量为1的物品种数有a1种,剩余物品数量为2的物品种数有a2种,剩余物品数量为3的物品种数有a3种,剩余物品数量为4的物品种数有a4种,上一次选择用来放在序列里面的物品种类还没有放之前还剩下的数量为last的方案数。

  这个我们先考虑初始状态,显然当全部为0时,无论last为什么方案数都是1,然后我们考虑转移,这里细节还是有的,就拿3为了例子,我现在把3的一种物品用掉一个,显然剩余3类的将减1,2的种数将+1,然后我们一共有a3种物品剩余数是3,所以now+=a3*dp[a1][a2+1][a3-1][a4][3](这个是错的,等下解释),但如果last==4,也就是上一次我是拿剩余数为4的物品转移过来的,也就是说我上次在序列里放到的某一种剩余数为4的物品,并且那种物品用掉了一个所以变成了剩余数为3的物品,所以剩余数为3的物品中一定有一种是我上次放的物品,所以要把哪一种减去。所以分析到这可以写出now+=(a3-(last==4))*dp(a1,a2+1,a3-1,a4,3)。

  但这个还是错的,因为即使是同一种,他们之间也是有区别的,同一种牌也有花色之分,还是拿3来说,剩余数为3的物品种类数为a3,我们但看每一种物品,他的剩余数为3,那么他一定有三种花色,也就是说,你打出一同一种牌中的一张(共同特点是剩余数都是3),放入序列,这一张牌三种可能的花色,所以总方案数要乘以3,即now+=(a3-(last==4))*dp(a1,a2+1,a3-1,a4,3)*3;。

 

代码:(是不是和着色方案很想啊)

#include
#include
#include
#include
#define ll long long#define ull unsigned long longusing namespace std;int num[6],pai[25];ull f[50][50][50][50][5];char s[20];ull dp(int a1,int a2,int a3,int a4,int last){ ull now=0; if((a1|a2|a3|a4)==0) return f[a1][a2][a3][a4][last]=1; if(f[a1][a2][a3][a4][last]) return f[a1][a2][a3][a4][last]; if(a1) now+=(a1-(last==2))*dp(a1-1,a2,a3,a4,1); if(a2) now+=(a2-(last==3))*dp(a1+1,a2-1,a3,a4,2)*2; if(a3) now+=(a3-(last==4))*dp(a1,a2+1,a3-1,a4,3)*3; if(a4) now+=a4*dp(a1,a2,a3+1,a4-1,4)*4; f[a1][a2][a3][a4][last]=now; return now;}int main(){ int t;cin>>t; int Case=0; while(t--){ int n; memset(f,0,sizeof(f)); memset(num,0,sizeof(num)); memset(pai,0,sizeof(pai)); scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%s",s); if(s[0]>='2'&&s[0]<='9') pai[s[0]-'0']++; else if(s[0]=='T') pai[10]++; else if(s[0]=='J') pai[11]++; else if(s[0]=='Q') pai[12]++; else if(s[0]=='K') pai[13]++; else if(s[0]=='A') pai[14]++; } for(int i=2;i<=14;i++) if(pai[i]) num[pai[i]]++; printf("Case #%d: %llu\n",++Case,dp(num[1],num[2],num[3],num[4],0)); } return 0;}

 

转载于:https://www.cnblogs.com/renjianshige/p/7593570.html

你可能感兴趣的文章
关于 error: LINK1123: failure during conversion to COFF: file invalid or corrupt 错误的解决方案...
查看>>
Linux 进程中 Stop, Park, Freeze【转】
查看>>
文件缓存
查看>>
PHP盛宴——经常使用函数集锦
查看>>
重写 Ext.form.field 扩展功能
查看>>
Linux下的搜索查找命令的详解(locate)
查看>>
MySQL查询优化
查看>>
android app启动过程(转)
查看>>
安装gulp及相关插件
查看>>
如何在Linux用chmod来修改所有子目录中的文件属性?
查看>>
Applet
查看>>
高并发环境下,Redisson实现redis分布式锁
查看>>
关于浏览器的cookie
查看>>
Hyper-V 2016 系列教程30 机房温度远程监控方案
查看>>
笔记:认识.NET平台
查看>>
cocos2d中CCAnimation的使用(cocos2d 1.0以上版本)
查看>>
【吉光片羽】短信验证
查看>>
gitlab 完整部署实例
查看>>
GNS关于IPS&ASA&PIX&Junos的配置
查看>>
影响企业信息化成败的几点因素
查看>>