码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 1637 Double Patience (概率DP)

时间:2018-09-27 22:10:39      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:arc   arch   tor   printf   inline   需要   ble   记忆化   ota   

题目

题目大意

\(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)

标签:arc   arch   tor   printf   inline   需要   ble   记忆化   ota   

原文地址:https://www.cnblogs.com/forth/p/9715556.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!