题目链接:https://nanti.jisuanke.com/t/44330
题意:有n个人玩游戏,每个人拥有k条生命。每轮每个人会有p的概率不会死,求最后是平局的概率
思路:设f[i][j]表示i轮后剩余j条生命的概率,那么 f[i][j] = p * f[i - 1][j] + (1 - p) * f[i - 1][j + 1]
由于生命都相同,P(平局) = 1 - P(某人赢) = 1 - n* P(第一个人赢) = 1 - n * sum( P(第一个人第i轮赢其余人i-1轮死) )
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fi first
#define se second
#define ls rt << 1
#define rs rt << 1|1
#define lson l, mid, ls
#define rson mid + 1, r, rs
#define pll pair<ll, ll>
#define pii pair<int, int>
#define ull unsigned long long
#define pdd pair<double, double>
const int mod = 1e9 + 7;
const int maxn = 1e3 + 10;
const int inf = 0x3f3f3f3f;
double f[maxn][maxn]; //f[i][j]表示i轮后剩余j条生命的概率
int main()
{
int n, m;
double p;
scanf("%d%d%lf", &n, &m, &p);
f[0][m] = 1;
for(int i = 1; i < maxn; ++i)
{
for(int j = m; j > 0; --j)
f[i][j] = p * f[i - 1][j] + (1 - p) * f[i - 1][j + 1];
f[i][0] = f[i - 1][0] + (1 - p) * f[i - 1][1]; //生命耗尽时不用乘以p
}
double ans = 0;
for(int i = 1; i < maxn; ++i) //1000次之后的概率对答案影响很小
{
ans += (f[i][0] - f[i - 1][0]) * pow(f[i - 1][0], n - 1); //计算在i轮死亡并且其他人都在i轮之前死亡的概率
}
printf("%.10f\n", 1 - n * ans);
return 0;
}