RedIsGood TopCoder - 9915(概率dp)
Posted 冰冻三尺 非一日之寒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RedIsGood TopCoder - 9915(概率dp)相关的知识,希望对你有一定的参考价值。
---恢复内容开始---
论文题:
桌面上有 R 张红牌和 B 张黑牌,随机打乱顺序后放在桌面上,开始一张一张
地翻牌,翻到红牌得到 1 美元,黑牌则付出 1 美元。可以随时停止翻牌,在最优
策略下平均能得到多少钱。
解析:
为什么要逆推。。。请看斌神解释。。。
dp[i][j] 代表 还剩i张红牌 和 j张黑牌时的期望钱数
有两种操作 不翻牌 和 翻牌 如果不翻牌 则dp[i][j] = 0
翻牌有两种情况 红牌+1 和 黑牌-1
当没有红牌时,我们就不拿了,这样才能保证最优
即 i == 0时 dp[i][j] = 0;
当存在红牌时 我们还有可能使总期望的钱数增加
所以dp[i][j] = max(0, i/(i+j) * (dp[i-1][j] + 1) + j/(i+j) * (dp[i][j-1] - 1));
摸了多少张红牌和黑牌都是随机的 所以下限是不确定的 上限确定 为R 和 B
所以从0 0 开始递推到R B
用滚动数组写一下就好了
#include <bits/stdc++.h> using namespace std; const int maxn=5010; class RedIsGood { public: double F[3][maxn]; double getProfit(int R, int B){ F[0][0]=0; int k = 0; for (int i=0;i<=R;i++) { k ^= 1; for (int j=0;j<=B;j++) { if ((i==0)&&(j==0)) continue; if (i==0) F[k][j]=0; else if (j==0) F[k][j]=F[k^1][j]+1; else F[k][j]=max(0.0,(1.0*i/(i+j)*(F[k^1][j]+1)+1.0*j/(i+j)*(F[k][j-1]-1))); } } return F[k][B]; } };
以上是关于RedIsGood TopCoder - 9915(概率dp)的主要内容,如果未能解决你的问题,请参考以下文章