Red is good题解

Red is good

时间限制: 1 Sec  内存限制: 64 MB

题目描述

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

输入

一行输入两个数R,B,其值在0到5000之间

输出

在最优策略下平均能得到多少钱。

样例输入

5 1

样例输出

4.166666

提示

输出答案时,小数点后第六位后的全部去掉,不要四舍五入.

solution:

    这题一开始想的是正着推,按照取得顺序拿,当红球数量小于黑球数量时跳出,但是那样会少考虑许多本来会出现的情况,于是需要反正来,ans[i][j]表示红球有i个黑球有j个的得分,ans[i][0]=i,ans[0][j]=0(因为此时没有红球了无法得分我们不会接着取),对于ij均不为0的举个例子,ans[2][1]有2/3的概率的一分然后到达状态ans[1][1]也有1/3的概率丢掉1分然后到达状态ans[2][0],所以ans[2][1]=2/3*(ans[1][1]+1)+1/3*(ans[2][0]-1);

所以转移的式子为ans[j][i-j]=(j/i)*(1+ans[j-1][i-j])+((i-j)/i)*(ans[j][i-j-1]-1);

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int r,b,now,state;
 8 double ans[2][5001];
 9 double max(double a,double b) {
10     return a>b?a:b;
11 }
12 int main() {
13     scanf("%d%d",&r,&b);
14     ans[0][0]=0;
15     tot=r+b;
16     for(int i=1; i<=tot; ++i) {
17         for(int j=min(i,r); j>=0; --j) {
18             if(i-j>b) {
19                 break;
20             }
21             if(i==j) {
22                 ans[j][0]=(double)j;
23                 continue;
24             }
25             if(!j) {
26                 ans[0][j]=(double)0;
27                 continue;
28             }
29             ans[j][i-j]=((double)j/(double)i)*(1+ans[j-1][i-j])+((double)(i-j)/(double)i)*(ans[j][i-j-1]-1);
30         }
31     }
32     printf("%0.6lf",ans[r][b]-0.0000005);
33     return 0;
34 }
炸内存的code

此时本菜鸡悲催的发现炸内存了,然后开了个滚动数组,上一个转移按照每一层,滚动数组则可以斜着一行行转移。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int r,b,now,state;
 8 double ans[2][5001];
 9 double max(double a,double b) {
10     return a>b?a:b;
11 }
12 int main() {
13     scanf("%d%d",&r,&b);
14     for(int i=1; i<=r; ++i) {
15         now=state^1;
16         ans[now][0]=(double)i;
17         for(int j=1; j<=b; ++j) {
18             ans[now][j]=max(0.0,((double)i/(double)(i+j))*(1+ans[state][j])+((double)j/(double)(i+j))*(ans[now][j-1]-1));
19         }
20         state^=1;
21     }
22     printf("%0.6lf",ans[state][b]-0.0000005);
23     return 0;
24 }

 

 

 

 

posted @ 2017-08-24 16:19  Forever_goodboy  阅读(499)  评论(0编辑  收藏  举报