题意:
一共有9堆牌,每堆牌四张。每次可以取堆顶点数相同的两张牌,如果有多种方案则选取是随机的。
如果最后将所有牌取完,则视为游戏胜利,求胜利的概率。
分析:
用一个九元组表示状态,分别代表每堆牌剩余的牌数。根据全概率公式,d[i]为后继状态成功概率的平均值。
#include <iostream>
#include <cstdio>
#include <map>
#include <vector>
using namespace std; map<vector<int>, double> d;
char card[][][]; double dp(vector<int>& cnt, int c)
{
if(c == ) return ; //所有的牌取完,游戏胜利概率为1
if(d.count(cnt) != ) return d[cnt];
double sum = ; //后继状态的总概率
int tot = ; //后继状态的数量
for(int i = ; i < ; ++i) if(cnt[i] > )
for(int j = i + ; j < ; ++j) if(cnt[j] > )
if(card[i][cnt[i]-][] == card[j][cnt[j]-][])
{
tot++;
cnt[i]--, cnt[j]--;
sum += dp(cnt, c-);
cnt[i]++, cnt[j]++;
}
if(tot == ) return d[cnt] = ;
return d[cnt] = sum / tot;
} bool read()
{
for(int i = ; i < ; ++i)
for(int j = ; j < ; ++j)
if(scanf("%s", card[i][j]) != )
return false;
return true;
} int main()
{
//freopen("in.txt", "r", stdin);
while(read())
{
vector<int> cnt(, );
d.clear();
printf("%.6f\n", dp(cnt, ));
} return ;
}
代码君