題目:ios
Double Patience是一種單人遊戲,使用標準的36張牌組。這些牌在洗牌後放在一張桌子上,疊成9疊,每疊4張,面朝上。數組
牌放下後,玩家轉身。每一次,他能夠從任意兩個牌堆中取出同一等級的頂級牌,而後將它們移除。若是有幾種可能性,玩家能夠選擇任何一種。若是全部的牌都從桌上移除,玩家將贏得遊戲,若是一些牌仍然在桌上,而且沒有有效的移動,玩家將失敗。spa
喬治喜歡這種遊戲。但當有幾種可能時,他不知道要選擇哪一張。喬治不想多想,因此在這種狀況下,他只需從可能的狀況中選擇一對隨機的,並刪除它。喬治選擇每種狀況的可能性相同。code
例如,若是最上面的牌是Ks、Kh、Kd、9h、8s、8d、7c、7d和6h,他會刪除任何一對在(KS, KH)、(KS, KD)、(KH, KD)、 (8S, 8D)和 (7C, 7D)中的任何一對。刪除(Ks,Kh)、(Ks,Kd)、(Kh,Kd)、(8s,8d)和(7c,7d)的機率都爲1/5。blog
請算出在遊戲開始時,根據桌上的牌,找出若是喬治按照描述行事,他贏得遊戲的可能.遊戲
大概意思就是說有 9 堆牌, 每堆 4 張, 當兩堆當前最頂上紙牌相同時能夠拿走, 問只要有能夠拿走的紙牌就拿走, 最後可以拿完紙牌的機率有多大ci
這題乍一看除了搜索並無什麼思路顯然是搜索題嘛io
能夠直接優雅簡單粗暴的開一個九維(確信)數組 class
ans[5][5][5][5][5][5][5][5][5]
記錄一下每一種狀況下的勝率stream
這樣咱們能夠知道:
當牌拿完時獲勝, 即 ans[0][0][0][0][0][0][0][0][0] = 1;
而後就能夠寫循環暴力枚舉每一種狀況了.
每找到一種拿牌方案, 這一層搜索的總方案數+1;
這一層搜索的勝率就是 (全部找到的方案的勝率之和) / (全部找到的方案數)
找不到方案時勝率顯然是0;
因此這題須要用到記憶化
一個方案若是被搜過了, 就直接返回勝率而不向下枚舉
因此再開一個bool數組記錄訪問狀態
那麼邊界就是沒有牌的狀態是訪問過的(即直接返回ans[0][0][0][0][0][0][0][0][0] = 1)
這題就AC了
下面是代碼
1 /* 2 思路:DFS 3 開兩個九維(確信)數組,一個double型,用來記錄每一堆每一層紙牌的勝率 4 固然能夠暴搜,可是會TLE,因此第二個bool類型的數組便派上用場了:記憶化 5 bool類型這個數組記錄一個狀況有沒有經歷過 6 每一種狀況的勝率:從這一種狀況開始搜的勝率之和除以全部搜到的狀況之和 7 當搜到一層沒法再次往下搜索時該狀態勝率爲0 8 當紙牌能被搜完時勝率爲1 9 花色對結果不形成影響 10 */ 11 12 # include <cstdio> 13 # include <iostream> 14 15 using namespace std; 16 17 int poker[10][5]; // 九堆紙牌一堆四個 18 double ans[5][5][5][5][5][5][5][5][5]; 19 bool vis[5][5][5][5][5][5][5][5][5]; 20 21 double dfs(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8, int h9){ 22 if(vis[h1][h2][h3][h4][h5][h6][h7][h8][h9]) 23 return ans[h1][h2][h3][h4][h5][h6][h7][h8][h9]; 24 vis[h1][h2][h3][h4][h5][h6][h7][h8][h9] = true; // 記憶化 25 26 int height[20] = {0, h1, h2, h3, h4, h5, h6, h7, h8, h9}; // 記錄每堆紙牌高度 27 28 double sumRate = 0.0; // 記錄勝率 29 double sumSol = 0; // 記錄找到的取牌方法總數 30 31 for(int i = 1; i <= 9; i++){ 32 for(int j = i + 1; j <= 9; j++){ 33 if(height[i] > 0 && height[j] > 0 && poker[i][height[i]] == poker[j][height[j]]){ 34 height[i] -= 1; 35 height[j] -= 1; 36 sumSol += 1; 37 // if(height[1]>=0&&height[2]>=0&&height[3]>=0&&height[4]>=0&&height[5]>=0&&height[6]>=0&&height[7]>=0&&height[8]>=0&&height[9]>=0) 38 sumRate += dfs(height[1], height[2], height[3], height[4], height[5], height[6], height[7], height[8], height[9]); 39 height[i]++; 40 height[j]++; 41 } 42 } 43 } 44 45 if(sumSol > 0) return ans[h1][h2][h3][h4][h5][h6][h7][h8][h9] = sumRate / sumSol; 46 else return ans[h1][h2][h3][h4][h5][h6][h7][h8][h9]; 47 } 48 49 int main(){ 50 vis[0][0][0][0][0][0][0][0][0] = 1; 51 ans[0][0][0][0][0][0][0][0][0] = 1.00; 52 char p1[3], p2[3], p3[3], p4[3]; 53 for(int i = 1; i <= 9; i++){ 54 cin>>p1>>p2>>p3>>p4; 55 poker[i][1] = p1[0] - '0'; 56 poker[i][2] = p2[0] - '0'; 57 poker[i][3] = p3[0] - '0'; 58 poker[i][4] = p4[0] - '0'; 59 } 60 61 printf("%.6lf", dfs(4, 4, 4, 4, 4, 4, 4, 4, 4)); 62 63 return 0; 64 }
就這樣吧