题意:一个岛上有石头,剪刀和布,规则就不用说了,问你最后只剩下每一种的概率是多少。
析:很明显的一个概率DP,用d[i][j][k]表示,石头剩下 i 个,剪刀剩下 j 个,布剩下 k 个,d[r][s][p] = 1,那状态转发方程怎么写呢?是这样的
如果石头减少了1,那么肯定是布干的,那么是哪个布干掉了哪个石头呢?这又是另一个问题,答案就是 i * k,那么总数就是 i * k + i * j + j * k。
最后再把各项加起来即可。
代码如下:
#include <iostream> #include <cstdio> using namespace std; const int maxn = 100 + 5; double d[maxn][maxn][maxn]; int main(){ int r, p, s; cin >> r >> s >> p; d[r][s][p] = 1; for(int i = r; i >= 0; --i){ for(int j = s; j >= 0; --j){ for(int k = p; k >= 0; --k){ // if(!i && !j && !k) continue; double sum = i * j + i * k + k * j; if(!sum) continue; if(i && k) d[i-1][j][k] += d[i][j][k] * i * k / sum; if(i && j) d[i][j-1][k] += d[i][j][k] * i * j / sum; if(j && k) d[i][j][k-1] += d[i][j][k] * j * k / sum; } } } double ansr = 0, ansp = 0, anss = 0; for(int i = 1; i <= r; ++i) ansr += d[i][0][0]; for(int i = 1; i <= s; ++i) anss += d[0][i][0]; for(int i = 1; i <= p; ++i) ansp += d[0][0][i]; printf("%.12lf %.12lf %.12lf\n", ansr, anss, ansp); return 0; }