NOIP模拟 赌博游戏 - 概率dp

题意:

最近西雅图的高中校园里流行这样一个游戏。

我们有一个骰子,这个骰子有M个面,分别写着1..M,并且是个公平的骰子,换句话说,一次投掷时每个面朝上的概率是相同的。

游戏的组织者使用这个骰子进行N次投掷,并且告诉玩家点数v出现了至少一次。那么玩家需要猜测N次投掷的点数之和。如果猜对了,就赢得了这个游戏。

小宇也喜欢玩这个游戏。在一次游戏中,她猜测了一个正整数sum,于是她想知道猜对的概率是多少。

分析:

设f[i][j][0/1]表示猜了i次,和为j,有(1)没有(0)猜中过v的概率。

转移很简单:

\(f[i][j][k == v] += f[i - 1][j - k][0]\)

\(f[i][j][1] += f[i - 1][j - k][1]\)

最后答案为: \(\frac{f[n][sum][1]}{\sum{f[n][j][1]}}\)

code

#include<bits/stdc++.h>
using namespace std;
int n, m, sum, v;
double tot, f[60][2600][2]; int main(){
freopen("h.in", "r", stdin);
scanf("%d%d%d%d", &n, &m, &v, &sum);
f[0][0][0] = 1;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n * m; j++){
for(int k = 1; k <= m; k++){
f[i][j][k == v] += 1.0*f[i - 1][j - k][0] / (1.0*m);
f[i][j][1] += 1.0*f[i - 1][j - k][1] / (1.0*m);
}
}
}
for(int i = 1; i <= n * m; i++) tot += f[n][i][1];
printf("%.8f", f[n][sum][1] / tot);
return 0;
}
上一篇:【图灵杯 A】谷神的赌博游戏


下一篇:ASP.NET Core 1.0基础之依赖注入