您的位置:首页 > 其它

NOIP模拟(11.02)T4 赌博游戏

2017-11-02 19:17 351 查看
赌博游戏
题目背景:
11.02 NOIP模拟T4
分析:DP
 
讲道理这个题比T3简单的多啊······直接定义f[i][j]表示已经投掷了i次,目前的和是j的方案数,一次枚举转移的时候用1
~ m都进行转移,第二次再DP一遍f[i][j],这一次的转移跳过v不进行枚举,然后两次的f
[sum]相减,就是一定包含至少一次v并且sum满足答案的方案数,然后因为至少出现一次v的总方案数为mn -
(m - 1)n,直接用之前两次的差值除以总方案数就可以了,注意要用double。
Source:
/*
created by scarlyw
*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <cctype>
#include <vector>
#include <queue>
#include <set>
#include <ctime>

const int MAXN = 50 + 10;

double ans = 0;
long double f[MAXN][MAXN * MAXN | 1];
int n, m, v, sum;

int main() {
freopen("gamb.in", "r", stdin);
freopen("gamb.out", "w", stdout);
scanf("%d%d%d%d", &n, &m, &v, &sum);
f[0][0] = 1;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n * m; ++j)
for (int k = 1; k <= j && k <= m; ++k)
f[i][j] += f[i - 1][j - k];
ans = f
[sum];
memset(f, 0, sizeof(f));
f[0][0] = 1;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n * m; ++j)
for (int k = 1; k <= j && k <= m; ++k) {
if (k == v) continue ;
f[i][j] += f[i - 1][j - k];
}
ans -= f
[sum];
long double l = 1, r = 1;
for (int i = 1; i <= n; ++i) l *= (long double)(m - 1), r *= (long double)m;
ans /= (r - l);
printf("%0.8f", (double)ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: