码迷,mamicode.com
首页 > 其他好文 > 详细

RedIsGood TopCoder - 9915(概率dp)

时间:2018-09-29 14:24:46      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:分享   pre   style   image   include   namespace   its   解析   顺序   

---恢复内容开始---

论文题:

  桌面上有 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)

标签:分享   pre   style   image   include   namespace   its   解析   顺序   

原文地址:https://www.cnblogs.com/WTSRUVF/p/9723209.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!