*UVA10900_So you want to be a 2n-aire? _概率dp_連續概率
阿新 • • 發佈:2019-02-15
題意
初始有1元,依次回答 n 道題,看到第 i 題時已知答對的概率,可選擇
1.答題:答錯收入0,答對乘2
2.不答:拿錢離開
每道題的概率為 t 到1的均勻分佈。
每次答題前知道概率做出最優決策,求得到的錢的期望。
思路
求期望為倒推的dp
設 e[i] 為已答對 i 題時的最終能得到的錢的期望,e[i] 是分為兩部分關於x的積分,x 為 t 到 1 間的均勻分佈
e[i] = ∫1/(1 - t) * 2^i * dx (x * e(i + 1) < 2^i) + ∫1/(1 - t) * x * e[i + 1] * dx (x >= ... && x <= 1)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define INF 0x3f3f3f3f #define rep0(i, n) for (int i = 0; i < n; i++) #define rep1(i, n) for (int i = 1; i <= n; i++) #define rep_0(i, n) for (int i = n - 1; i >= 0; i--) #define rep_1(i, n) for (int i = n; i > 0; i--) #define MAX(x, y) (((x) > (y)) ? (x) : (y)) #define MIN(x, y) (((x) < (y)) ? (x) : (y)) #define mem(x, y) memset(x, y, sizeof(x)) #define MAXN 40 using namespace std; const double eps = 1e-8; int n; double t, ans, e[MAXN]; void solve() { ans = 0; e[n] = 1 << n; for (int i = n - 1; i >= 0; i--) { double tmp = 1.0 * (1 << i) / e[i + 1]; e[i] = 0; if (tmp > t) e[i] = (tmp - t) / (1 - t) * (1 << i); tmp = MAX(tmp, t); e[i] += e[i + 1] / (1 - t) / 2 * (1 - tmp * tmp); } printf("%.3f\n", e[0]); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif // ONLINE_JUDGE while (scanf("%d %lf", &n, &t) != EOF && n) { solve(); } return 0; }