【BZOJ1419】Red is good 期望DP

题目大意

  桌面上有\(R\)张红牌和\(B\)张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到\(1\)美元,黑牌则付出\(1\)美元。可以随时停止翻牌,在最优策略下平均能得到多少钱。

  \(0\leq R,B\leq 5000\)

题解

  设\(f_{i,j}\)为还剩下\(i\)张红牌和\(j\)张黑牌时的最大收益。每次可以选择翻或者不翻。

\[\begin{align} f_{i,0}&=i\\ f_{0,i}&=0\\ f_{i,j}&=\max(0,\frac{i(f_{i-1,j}+1)+j(f_{i,j-1}-1)}{i+j}) \end{align} \]

  最后答案是\(f_{R,B}\)

  辣鸡出题人卡空间要用滚动数组才能过

  时间复杂度:\(O(RB)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
double f[2][5010];
int main()
{
//	freopen("bzoj1419.in","r",stdin);
	int n,m;
	scanf("%d%d",&n,&m);
	int i,j;
	int t=0;
	for(i=0;i<=n;i++)
	{
		t^=1;
		f[t][0]=i;
		for(j=1;j<=m;j++)
			f[t][j]=max(0.,(f[t^1][j]+1)*double(i)/(i+j)+(f[t][j-1]-1)*double(j)/(i+j));
	}
	ll s=f[t][m]*1000000;
	printf("%lld.%.6lld\n",s/1000000,s%1000000);
	return 0;
}
posted @ 2018-03-05 21:08  ywwyww  阅读(230)  评论(0编辑  收藏  举报