小明被劫持到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 }
动态规划比深搜快好多。。。。。