题意:一个初始中奖率q=2%,每次玩一局游戏,如果游戏赢了就抽奖,没抽到就q+2,然后继续玩游戏,如果游戏输了就q+1.5。问玩的游戏局数的期望,并且中奖率最高为100%
题解:初始中奖率为q%,输入的是游戏的获胜概率p%,dp[i]为获奖概率为 i 时的期望。因为q%最高为100%,所以初始状态为dp[100],但是因为如果游戏输了的话是p+1.5,而数组的下标是不能用小数的,所以我们整体扩大2倍,初始状态设为dp[200]。
当q = 100%的时候,显然dp[200] = 1 / p。转移方程dp[q]=p⋅(1−q)⋅dp[min(q+4,200)]+(1−p)dp[min(q+3,200)]+1,
其中1是当前局
p⋅(1−q)⋅dp[min(q+4,200)]为游戏获胜但是未中奖的期望
(1−p)dp[min(q+3,200)]为游戏失败的期望,三者和即为概率为q时的期望
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<stack> #include<cstdlib> #include<queue> #include<set> #include<string.h> #include<vector> #include<deque> #include<map> using namespace std; #define INF 0x3f3f3f3f #define eps 1e-10 typedef long long LL; const int MAXN = 10 + 5; const int mod = 998244353; int main() { int _ = 1,t; cin >> t; while(t--) { double p; cin >> p; p /= 100.0; double dp[210]; memset(dp,0,sizeof dp); dp[200] = 1/p; for(int i = 199; i >= 4; i --) { dp[i] = p * (1 - i * 1.0 / 200.0) * dp[min(i + 4,200)] + (1 - p) * dp[min(i + 3,200)] + 1; } printf("Case %d: %.10lf ",_++,dp[4]); } }