第六届蓝桥杯省赛---牌型种数

小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?

请填写该整数,不要填写任何多余的内容或说明文字。

分析:

方法一:暴力

这道题可以直接上暴力(13个for循环的嵌套),但是代码比较冗长,可以自己写一下。。。

方法二:dfs

直接深搜,递归决定这张牌是要还是不要  

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int cnt=0;//记录多少种牌型
 5 /*sum代表手中总共有几张牌,current代表该抽取第几章牌*/
 6 void search(int sum,int current){
 7     if(current>13||sum>13) return ;
 8     if(sum==13){
 9         cnt++;
10         return ;
11     }
12     /*dfs这张牌要还是不要,不要的话0张,要的话1~4张*/
13     for( int i=0; i<=4; i++ ){
14         search(sum+i,current+1);
15     }
16 }
17 
18 int main(){
19     search(0,0);
20     cout<<cnt<<endl;
21     return 0;
22 }

方法三:动态规划

自己不太会用动态规划,从网上瞄了一眼别人的代码。。。动态规划是一块难啃的骨头,自己还是要好好学啊。。。。

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int dp[14][14]; // dp[i][j]: 当前到第i张牌,总共有j张牌时的解的个数
 6 
 7 int main() {
 8 
 9     dp[1][0] = dp[1][1] = dp[1][2] = dp[1][3] = dp[1][4] = 1;
10 
11  
12 
13     for (int i = 2; i <= 13; i++) {
14 
15         for (int k = 0; k <= 13; k++) {
16 
17             if (k - 4 >= 0) dp[i][k] += dp[i-1][k-4];
18 
19             if (k - 3 >= 0) dp[i][k] += dp[i-1][k-3];
20 
21             if (k - 2 >= 0) dp[i][k] += dp[i-1][k-2];
22 
23             if (k - 1 >= 0) dp[i][k] += dp[i-1][k-1];
24 
25             dp[i][k] += dp[i-1][k];
26 
27         }
28 
29     }
30 
31     cout << dp[13][13] << endl;
32 
33     return 0;
34 
35 }

动态规划比深搜快好多。。。。。

猜你喜欢

转载自www.cnblogs.com/Bravewtz/p/10392664.html