题意:一个岛上有石头,剪刀和布,规则就不用说了,问你最后只剩下每一种的概率是多少。
析:很明显的一个概率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;
}
浙公网安备 33010602011771号