求概率dp的一个当前状态可以由它的几个子状态推出来,推导的过程一般是从后往前推的,E(apa+bpb+cpc…)=aE(pa)+bE(pb)+cE(pc)+…+1。由当前状态可以逆推出前面几个子状态。
今天补了之前比赛的一道概率dp的题目
题目链接如下:
https://acm.hdu.edu.cn/showproblem.php?pid=6555
题目思路:
这道题的思路其实不难几种子状态当时也都推出来了但是我学过概率dp也没看出来这题可以dp于是比赛就没写出来。其实这题能看出是概率dp的话也不难,每次转移有3个状态一种是赢了比赛但是没抽到是p*(1-q)dp[j+2]还有一种是比赛输了是(1-p)dp[j+1.5]还有一种是比赛赢了并且抽到了是pq这种情况直接就结束了所以不用管他。
所以状态转移方程是dp[j]=(1-p)dp[j+1.5]+p(1-q)*dp[j+2]+1。而这个下标可能是小数那我们让他总体乘上2就行。
代码如下
#include<iostream>
using namespace std;
const int N=1000;
double dp[N];
int main(){
int t;
double p;
scanf("%d",&t);
for(int i=1;i<=t;i++){
scanf("%lf",&p);
p/=100;
dp[200]=1/p;
for(int j=199;j>=4;j--){
dp[j]=p*(1-1.0*j/200)*dp[min(j+4,200)]+(1-p)*dp[min(j+3,200)]+1;
}
printf("Case %d: %.10f\n",i,dp[4]);
}
return 0;
}