牌型种数
小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少
种呢?
请填写该整数,不要填写任何多余的内容或说明文字。
解析:只考虑点数,则13张牌中某点数的牌数最少有0张,最多有4张。
答案:3598180
方法一:暴力求解
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
int count = 0;
for(int A1 = 0; A1 <= 4; A1++)
for(int A2 = 0; A2 <= 4; A2++)
for(int A3 = 0; A3 <= 4; A3++)
for(int A4 = 0; A4 <= 4; A4++)
for(int A5 = 0; A5 <= 4; A5++)
for(int A6 = 0; A6 <= 4; A6++)
for(int A7 = 0; A7 <= 4; A7++)
for(int A8 = 0; A8 <= 4; A8++)
for(int A9 = 0; A9 <= 4; A9++)
for(int A10 = 0; A10 <= 4; A10++)
for(int AJ = 0; AJ <= 4; AJ++)
for(int AQ = 0; AQ <= 4; AQ++)
for(int AK = 0; AK <= 4; AK++)
{
if(A1+A2+A3+A4+A5+A6+A7+A8+A9+A10+AJ+AQ+AK == 13)
{
count++;
}
}
cout<<count<<endl;
return 0;
}
方法二:DFS 以牌的点数深度遍历
深度遍历退出条件:
1. 牌数目大于13张,直接退出
2. 牌点数达到13点时,牌数目正好13张,计数加一,退出
深度遍历条件:牌点数未达到13点,牌数目未达到13张
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int count = 0;
//以牌的类型深度遍历
void dfs(int cardNum,int sum)
{//点数,当前手里的牌数
if(sum > 13)
return;
if(cardNum == 13)
{
if(sum == 13)//遍历了所有点的牌,手里正好13张牌时满足条件
count++;return;
}
for(int i = 0; i <= 4; i++)
{
dfs(cardNum + 1,sum + i);
//上句功能同下三句作用相同
//sum += i;
//dfs(cardNum +1,sum);
//sum -= i; //还原
}
}
int main(int argc, char** argv) {
dfs(0,0);
cout<<count<<endl;
return 0;
}
方法三:提高DFS效率
深度遍历退出条件:
1.牌数目达到13张,计数加一,退出
2.牌数目不足13张,牌点数达到13点,直接退出
深度遍历条件:
牌数目不足13张,同时牌点数达到13点
效率提高点:(看代码)
#include <iostream>
using namespace std;
//* run this program using the console pauser or add your own getch, system("pause") or input loop */
int count = 0;
//
//以牌的类型深度遍历
void dfs(int cardNum,int sum)//参数一:点数; 参数二:当前手里的牌数
{
if(sum == 13)
{//手里正好13张牌时满足条件
count++;
return;
}
if(cardNum==13) {
return; //遍历完所有点数依旧补够13张,返回,满足条件的情况次数不变
}
//当剩余牌数小于4时,就可以减少多余遍历路径,提高BFS效率
//同时不会出现sum > 13 的情况
int num = min(13-sum,4);
for(int i = 0; i <= num; i++)
{
dfs(cardNum + 1,sum + i);
}
return;
}
int main(int argc, char** argv) {
dfs(0,0);
cout<<count<<endl;
return 0;
}
借鉴: