UVa 1637 Double Patience (概率DP)
阿新 • • 發佈:2018-09-28
gis tab span 記憶化搜索 code 記憶化 rac print ble 記錄情況。
題目
題目大意
\(36\)張牌分成\(9\)堆, 每堆\(4\)張牌。每次可以拿走某兩堆頂部的牌, 但需要點數相同。如果有多種拿法則等概率的隨機拿。例如, \(9\)堆頂部的牌分別為KS
, KH
, KD
, 9H
, 8S
, 7C
, 7D
, 6H
, 則有\(5\)種拿法(KS
, KH
), (KS
, KD
), (KH
, KD
), (8S
, 8D
), (7C
, 7D
), 每種拿法的概率均為\(\frac{1}{5}\)。如果最後拿完所有牌則遊戲成功。按順序給出每堆牌的\(4\)張牌, 求成功概率。
題解
記憶化搜索每一種情況, 使用一個std::map<std::vector<int> >
代碼
#include <map> #include <cstdio> #include <vector> std::map<std::vector<int>, double> hash_table; char card[9][4][7]; inline double DepthFirstSearch(register std::vector<int>&, const int&); int main(int argc, char const *argv[]) { while (~scanf("%s", card[0][0])) { for (register int c(1); c < 4; ++c) scanf("%s", card[0][c]); for (register int r(1); r < 9; ++r) { for (register int c(0); c < 4; ++c) { scanf("%s", card[r][c]); } } hash_table.clear(); register std::vector<int> status(9, 4); printf("%.6lf\n", DepthFirstSearch(status, 36)); } } inline double DepthFirstSearch(register std::vector<int> &status, const int &c) { if (!c) return 1.0; if (hash_table.count(status)) return hash_table[status]; register int total(0); register double sum(0); for (register int t(0); t < 9; ++t) if(status[t] > 0){ for (register int i(t + 1); i < 9; ++i) if (status[i] > 0) { if (card[t][status[t] - 1][0] != card[i][status[i] - 1][0]) continue; ++total, --status[t], --status[i], sum += DepthFirstSearch(status, c - 2), ++status[t], ++status[i]; } } hash_table[status] = total ? sum / double(total) : 0.0; return hash_table[status]; }
UVa 1637 Double Patience (概率DP)