[BZOJ1419] Red is good
2018-03-27 14:10
351 查看
Description
桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元。可以随时停止翻牌,在最优策略下平均能得到多少钱。Input
一行输入两个数R,B,其值在0到5000之间Output
在最优策略下平均能得到多少钱。Sample Input
5 1Sample Output
4.166666HINT
输出答案时,小数点后第六位后的全部去掉,不要四舍五入.解题分析
显然为期望概率DP。 我们设 dp[r]dp[r][b]表示还剩r张红牌, b张黑牌时的期望收益,则有转移方程:dp[r][b]=max(0,(dp[r−1][b]+1)×rr+b+(dp[r][b−1]−1)×br+bdp[r][b]=max(0,(dp[r−1][b]+1)×rr+b+(dp[r][b−1]−1)×br+b
特别地, dp[i][0]=idp[i][0]=i,dp[0][i]=0dp[0][i]=0,因为收益为负还不如不选….
算一算复杂度, 大概是O(2e7)O(2e7)左右, 但因为是double运算速度感人, 所以我们必须把数组卡进[b]三级缓存,所以必须使用滚动数组。同时这个输出也是坑人啊…
代码如下:
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <cctype> #include <algorithm> using namespace std; #define R register #define IN inline #define gc getchar() #define W while #define MX 5005 #define db double db dat[2][MX]; int main(void) { int r, b; scanf("%d%d", &r, &b); R int n = 0; for (R int i = 0; i <= r; ++i) { n ^= 1; dat [0] = i; for (R int j = 1; j <= b; ++j) dat [j] = max(0.0, (dat[n ^ 1][j] + 1) * (double)i / (i + j) + (dat [j - 1] - 1) * (double)j / (i + j)); } long long ans = dat [b] * 1000000; printf("%lld.%.6lld", ans / 1000000, ans % 1000000); return 0; }
相关文章推荐
- 【BZOJ】1419 Red is Good
- bzoj 1419: Red is good
- 【期望DP】BZOJ1419[Red is good]题解
- 【BZOJ】1419 Red is good
- 【BZOJ1419】Red is good
- 【BZOJ】【1419】Red is good
- BZOJ 1419 Red is good ——期望DP
- 【BZOJ1419】【期望DP】Red is good 题解
- BZOJ 1419 Red is good
- Bzoj1419 Red is good
- BZOJ——1419: Red is good
- BZOJ1419 Red is good
- 【bzoj 1419】Red is good(期望DP)
- BZOJ 1419: Red is good(期望DP)
- bzoj 1419 Red is good(期望DP)
- BZOJ 1419: Red is good 期望DP
- bzoj 1419: Red is good 期望dp
- bzoj1419: Red is good
- BZOJ 1419: red is good
- 【BZOJ1419】Red is good(期望DP)