bzoj 1419

Description
桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元。可以随时停止翻牌,在最优策略下平均能得到多少钱。
Input
一行输入两个数R,B,其值在0到5000之间
Output
在最优策略下平均能得到多少钱。
题解:

/*
    Prog:bzoj 1419
    Solu: 
        f[i][j]表示i个红的j个黑的期望收益。
        f[i][j] = max{(f[i - 1][j] + 1) * (1.0 * i / (i + j)) + (f[i][j - 1] - 1) * (1.0 * j / i + j),0}; 
    然后本来是记忆化搜索的。
    然而发现……
    搜什么搜……递推!
    卡空间……
    滚动数组……

*/
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#define Rep(i,n) for(int i = 1; i <= n ; i ++)
#define RepG(i,x) for(int i = head[x] ;~ i ; i = edge[i].next)
#define Rep_d(i,n) for(int i = n ; i > 0 ; i --)
#define Rep_0(i,n) for(int i = 0 ; i < n ; i ++)
#define RD(i,x,n) for(int i = x; i <= n ; i ++)
#define CLR(a,b) memset(a,b,sizeof(a))
#define RDD(i,x,n) for(int i = x; i >= n; i --)
#define lc ch[0]
#define rc ch[1]
#define v edge[i].to
#define ulfc t[u.lc]
#define urtc t[u.rc]
using namespace std;
const int inf = 1 << 30;
typedef long long ll;
int read(){
    char ch = getchar();
    while((ch < '0' || ch > '9') && ch != '-')ch = getchar ();
    int x = 0;
    bool flag = 0;
    if(ch == '-')ch = getchar(),flag = 1;
    while(ch >= '0' && ch <= '9')x = (x << 1) + (x << 3) + ch - '0',ch = getchar ();
    return flag ? -x : x;
}
int n,m;
const int N = 5005;
double f[2][N];
int main (){
    n = read(),m = read();
    Rep(i,n)
    {
        f[i & 1][0] = i;
        Rep(j,m)
            f[i & 1][j] = max( (f[i & 1 ^ 1][j] + 1) * (1.0 * i / (i + j)) + (f[i & 1][j - 1] - 1) * (1.0 * j / (i + j)),0.0);
    }
    printf("%.6f\n",f[n & 1][m] - (5e-7));
    return 0;
}

大概就这样。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值