藍橋杯 牌型種數 DFS


牌型種數

小明被劫持到X賭城,被迫與其他3人玩牌。
一副撲克牌(去掉大小王牌,共52張),均勻發給4個人,每個人13張。
這時,小明腦子里突然冒出一個問題:
如果不考慮花色,只考慮點數,也不考慮自己得到的牌的先后順序,自己手里能拿到的初始牌型組合一共有多少種呢?

請填寫該整數,不要填寫任何多余的內容或說明文字。


思路:dfs //結果:3598180,比賽得到這么大的答案,也不敢填T^T

相當於有13個桶,每個桶里面最大取4

從第一個桶開始取,取值0~4,達到數目13,跳出,達不到,判斷是否越界。未越界,那么就接着搜索,從下一桶開始艘。

//有人來問,可能我解釋的不太清楚,所以回來補充了QAQ

一共是52張牌,不算花色的話就是13種類型,我用0~12來編號。然后0~12個桶里面每個桶都有4張花色不同的牌。程序從第0號桶開始搜索,當前沒有選取牌,所以此時選出牌的數量就是0。dfs()函數中的參數pos代表當前搜索到哪個桶,cnt表示已經選取出來的牌數。先不考慮遞歸出口。跳過dfs中兩個if判斷。num取得是4和13-cnt中的小值。因為當前桶還沒有選取最多有4張牌。但是需要注意的是,假如搜到當前位置時選出來的牌數已經達到了11張,而我們每人只能夠拿走13張牌,所以當前位置我們最多只能再選取兩張。一個是2,一個是4,很明顯,當前桶可取的數量一定會選取較小的數值當作實際容量。再下一個for循環中我們需要做的就是確定當前桶中要拿走的數量,一張一張拿,再去搜下一個位置。當我們搜下一個位置時發現我們手中的牌已經達到了13張,那么祝賀你,已經搜尋到了一種可行方案,總方案數sum++,然后return。如果當前牌數沒有到達13張,但是搜尋的位置到了13號桶,對不起我家沒有那么多桶(注意程序中是從0開始編號的),此刻直接返回上一個位置和牌數,搜尋下一個可行方案。

因為整個都是按找順序搜尋的,桶的位置從0到12,手中的牌一張一張遞增,所以不會出現重復的方案。要是還不明白,就線照着程序在紙上畫一畫就懂了。T^T。

代碼:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
int sum=0;
void dfs(int pos, int cnt){
    if(cnt==13){
        sum++;
        return;
    }
    if(pos==13){
        return;
    }
    int num=min(13-cnt,4);//min取兩者中的小值
    for(int i=0;i<=num;i++){
        dfs(pos+1,cnt+i);
    }
    return;
}
int main(){
    dfs(0,0);
    printf("%d\n",sum);
    return 0;
}



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM