TopCoder SRM420 Div1 500pt RedIsGood

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

R,B ≤ 100000.

输入格式:

若干行,每行两个整数R,B

输出格式:

一个实数期望值.

样例输入:

68 7

样例输出

61.103

分析:这道题加深了我对期望+dp的理解.考虑dp,设f[i][j]表示还剩下i张红牌j张黑牌的期望值,这个时候如果停止翻牌,那么f[i][j] = 0,如果继续翻牌,就有i/i+j的概率翻到红牌,j/i+j的概率翻到黑牌,那么f[i][j] = (f[i-1][j] + 1) * i/(i + j) + (f[i][j-1] - 1) * j/(i + j).

这个时候我就有点疑惑了,为什么这个方程的期望值f[i-1][j],f[i][j-1]要乘上概率而noip2016d1t3那道题不需要呢?经过长时间的思索,我终于明白了,换教室那道题不用乘概率是因为那是两个不同的决策,它们并不在同一个决策里,而这一题要么不翻,要么翻,而实际上期望都在同一个决策里,所以有几率翻到红牌或者黑牌,所以要乘上概率.

一般期望题首先要考虑有没有公式,然后试试dp,dp的话一边直接用期望值表示状态.

数据过大,用了滚动数组.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

int r,b,last = 0,now = 1;

const int maxn = 1e5+10;

double f[2][maxn];

int main()
{
    while (scanf("%d%d",&r,&b))
    {
        memset(f,0,sizeof(f));
        for (int i = 1; i <= r; i++)
        {
        f[now][0] = i;
        for (int j = 1; j <= b; j++)
        f[now][j] = max(0.0,(f[last][j] + 1) * i/(i + j) + (f[now][j-1] - 1) * j / (i + j));
        swap(now,last);
        }
        printf("%.3lf\n",f[last][b]);
    }

    return 0;
}
时间: 2024-11-05 12:28:56

TopCoder SRM420 Div1 500pt RedIsGood的相关文章

[TopCoder SRM420 Div1 500pt RedIsGood]【数学期望】【动态规划】

[题意] 桌面上有R 张红牌和B 张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1 美元,黑牌则付出1 美元.可以随时停止翻牌,在最优策略下平均能得到多少钱. [思路]: 于是dp[0][0]=0 dp[i][j]=F[i-1][j]+1;     (j=0) dp[i][j]=0;               (i=0) dp[i][j]= max(0.0,(dp[i-1][j]+1)*(i/(i+j))  +  (dp[i][j-1])*(j/(i+j))); 最后dp[

TopCoder 649 div1 &amp; div2

最近一场TC,做得是在是烂,不过最后challenge阶段用一个随机数据cha了一个明显错误的代码,最后免于暴跌rating,还涨了一点.TC题目质量还是很高的,非常锻炼思维,拓展做题的视野,老老实实补题吧. div2 250pts 题意:判断s去掉一个字符后能否和t一样. 代码: 1 class DecipherabilityEasy { 2 public: 3 string check(string s, string t) { 4 int n = s.size(); 5 int m = t

TopCoder 603 div1 &amp; div2

div2 250pts MiddleCode 题意:s串长度为奇数时,将中间字符取掉并添加到t末尾:长度为偶数时,将中间两个较小的字符取掉并添加到末尾. 分析:直接做,学习了一下substr(s, pos, len)返回s中从pos开始的长度为len的字串. 代码: 1 class MiddleCode { 2 public: 3 void Remove(string &s, int pos) { 4 int len = s.size(); 5 string t = ""; 6

topcoder SRM712 Div1 LR

题目: Problem Statement      We have a cyclic array A of length n. For each valid i, element i-1 the left neighbor of element i. Additionally, element n-1 is the left neighbor of element 0. You are given two vector<long long>s s and t, each with n ele

TopCoder SRM500 Div1 250 其他

原文链接https://www.cnblogs.com/zhouzhendong/p/SRM500-250.html SRM500 Div1 250 题意 (看题用了半个小时--) 有 n 个人(编号从 0 到 n-1)玩游戏,要通过投票的方式确定谁输.现在已知有一些人有明确的意见,认为谁输.具体地用一个 vector decision 来描述,vector decision 的大小可能不足 n . 定义一个集合 S 包含一些人,初始的时候集合 S 包含所有人.他们会进行若干轮投票,每一轮中,一

TopCoder SRM502 Div1 500 贪心 01背包

原文链接https://www.cnblogs.com/zhouzhendong/p/SRM502-500.html SRM502 Div1 500 好题. 首先,如果已经确定了解决所有问题的优先级,只需要对于每一个问题是否被解决做出决策,那么显然直接 01 背包就好了. 事实上,我们是可以贪心地确定两个问题的优先程度的. 对于两个问题,假设分别为 a 和 b,则先做 a 再紧接着做 b 和先做 b 再紧接着做 a 的收益之差为 \[ \begin{eqnarray*} &&(-dec_a

TopCoder SRM502 Div1 1000 动态规划

原文链接https://www.cnblogs.com/zhouzhendong/p/SRM502-1000.html SRM502 Div1 1000 题意 从 [0,n-1] 中选择 k 个不同的整数,使得他们的和是 n 的倍数,求方案数.对 \(10^9+7\) 取模. \(n\leq 10^9,k\leq 1000\) 题解 ? 首先我们考虑从 n 个里面选择 k 个并进行排列的方案数,最终只需要除以 k! 就好了. ? 设 \(M=n\) : ? 设 \(f(n,m,t)\) 表示 在

Topcoder SRM646 div1 600 bfs+剪枝

因为只有47个blocks,所以现在小范围内,即在-50 <= x <= 50,-50 <= y <= 50内进行bfs,之后尽量让点向右走,记录最大值. #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cm

Topcoder SRM655 DIV1 500 Nine

题意:这题是http://www.cnblogs.com/zyue/p/4436075.html 这题的加强版. 解题思路:根据dp规则,我们可以把d[i]值相同的放到一起,然后算一个总的DP就行了. 解题代码 1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 /*#line 7 "Nine.cpp" 7 #include <cstdlib> 8 #include <cctype> 9 #include &l