ps:初学概率dp,所以 就算是板子也 是看了非常久,好在最后还是学会了qwq…
文章目录
- 题意
- 思路
- 代码
- 总结
题意
思路
概率dp通常为从能够得到的状态去进行转移,在q为100%的时候,我们能够知道赢的概率为 p,那么赢的期望就是1/p,
那么往前转移状态,设dp[i]为机会率为i的时候的期望,那么
机会率为i时,一共有三种情况:
1.玩家赢了并且中奖了
2.玩家赢了但是没中奖
3.玩家没赢
对应的三种概率为
1.pq
2.p(1-q)
3.(1-p)
因为玩家赢了并且中奖了是直接结束游戏没有后续的状态,所以对于机会率为i的时候
赢的期望=1(这一把赢了并且中奖了)+p*(1-q)*dp[q+2](玩家赢了但是没中奖) +(1-p)*dp[q+1.5](玩家没赢) ;
但是因为1.5是小数,所以对于dp[i]扩大两倍即可(最后记得用浮点运算)。
代码
#include<cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include<vector>
#include<queue>
#include<map>
#define sc_int(x) scanf("%d", &x)
#define sc_ll(x) scanf("%lld", &x)
#define pr_ll(x) printf("%lld", x)
#define pr_ll_n(x) printf("%lld\n", x)
#define pr_int_n(x) printf("%d\n", x)
#define ll long long
using namespace std;
const int N=1000000+100;
int n ,m,h;
int s[N];
double dp[N];
void slove( int t )
{
double p;
cin>>p;//中奖率
p/=100;
memset(dp,0,sizeof dp);
dp[200]=1/p;//赢的机会为100的时候
for(int i =199;i>=4;i--)
dp[i]=1.0 + 1.0*(1-p)*dp[min(200,i+3)] + 1.0*p*(1-i*1.0/200)*dp[min(200,i+4)];
printf("Case %d: %.10lf\n",t,dp[4]);
}
int main()
{
int t;
sc_int(t);
for(int i =1;i<=t;i++)
slove(i);
return 0;
}
总结
因为dp没见过概率dp的题,所以初见的时候感觉很不知所措,以后就尽量看到不会的就去学学吧~