poj 3682 King Arthur's Birthday Celebration (期望dp)
解题思路
第一问比较简单,设$f[i]$表示扔了$i$次正面向上的硬币的期望,那么有转移方程 : $f[i]=f[i]*(1-p)+f[i-1]*p+1$,意思就是$i$次正面向上可以由$i-1$次扔一个正面或者$i$次扔一个背面得到,化简后可得 : $f[i]=f[i-1]+1/p$。
第二问就比较玄学了,设$g[i]$表示扔了$i$次正面向上花费的期望,那么考虑如果第$i$次到正面,其实次数等于$f[i-1]+1$,如果扔到背面,次数等于$f[i]+1$。所以转移方程:$g[i]=p*(g[i-1]+2*(f[i-1]+1)-1)+(1-p)*(g[i]+2*(f[i]+1)-1)$,化简后可得:$g[i]=g[i-1]+2*f[i-1]-2*f[i]+(1+2*f[i])/p$。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 1005; int k; double p,f[MAXN],g[MAXN]; int main(){ while(~scanf("%d",&k)){if(!k) break; scanf("%lf",&p); f[0]=0.0;g[0]=0.0; for(int i=1;i<=k;i++) f[i]=f[i-1]+1.0/p; for(int i=1;i<=k;i++) g[i]=g[i-1]+2*f[i-1]-2*f[i]+(1+2*f[i])/p; printf("%.3lf %.3lf\n",f[k],g[k]); } return 0; }