[ BZOJ 1419 ] Red is Good
阿新 • • 發佈:2018-11-13
\(\\\)
Description
桌面上有 \(R\) 張紅牌和 \(B\) 張黑牌,隨機打亂順序後放在桌面上,開始一張一張地翻牌。
翻到紅牌得到 \(1\$\),黑牌則付出\(1\$\)。可以隨時停止翻牌,在最優策略下平均能得到多少錢。
- \(R,B\le 5000\)
\(\\\)
Solution
期望水題。
所謂最優策略也就是不會使得得到的錢為負數,轉移的時候和 \(0\) 取 \(max\) 就是了。
注意,由於是牌序隨機,所以最後答案必須是全部牌的得分期望。
設 \(f[i][j]\) 表示拿了 \(i\) 張紅牌, \(j\) 張黑牌的期望得錢數。
\[ f[i][j]=max(0,\frac i{(i+j)\times(f[i][j]+1)}+\frac{j}{(i+j)*(f[i][j-1]-1))} \]
\(\\\)
Code
#include<cmath> #include<cstdio> #include<cctype> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 5010 #define R register #define gc getchar using namespace std; typedef long long ll; int n,m; double f[2][N]; int main(){ scanf("%d%d",&n,&m); for(R int i=0,now=0;i<=n;++i,now^=1,f[now][0]=(double)i){ for(R int j=1;j<=m;++j) f[now][j]=max(0.0,(double)i/(double)(i+j)*(f[now^1][j]+1)+(double)j/(double)(i+j)*(f[now][j-1]-1)); } ll ans=f[n&1][m]*1000000; printf("%lf",(double)ans/1000000); return 0; }