标签:
题意:一 个答题赢奖金的问题,玩家初始的金额为1,给出n,表示有n道题目,t表示说答对一道题目的概率在t到1之间,每次面对一道题,可以选择结束游戏,
获得当 前奖金;回答下一道问题,答对的概率p在t到1之间,答对的话奖金翻倍,答错的话结束游戏,没有奖金,求玩家赢的奖金的期望值的最大值。
析:首先是求期望,那就和平均值差不多,我们来分析第 i 道题时,两个情况,要么回答,要么不回答,如果不回答那么就是2^i,如果回答概率是p * 下一个题的概率,
那么比较期望谁的大,如果p * ans > 2 ^ i,那么就回答,那么我们只要求出临界值就好,也就是 p0 = 2 ^ i / ans,再利用全期望公式,加起来就好。
如果p0 < t,那么他一定回答这个题,如果小于等于,有两个情况,一种就是[t, p0], 一种是[p0, 1],加起来就好。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring> #include <set> #include <queue> #include <algorithm> #include <vector> #include <map> #include <cctype> using namespace std ; typedef long long LL; typedef pair<int, int> P; const int INF = 0x3f3f3f3f; const double inf = 0x3f3f3f3f3f3f3f; const double eps = 1e-8; const int maxn = 1e4 + 5; const int mod = 1e9 + 7; const int dr[] = {0, 0, -1, 1}; const int dc[] = {-1, 1, 0, 0}; int n, m; inline bool is_in(int r, int c){ return r >= 0 && r < n && c >= 0 && c < m; } double ans[35]; double t; double solve(){ if(fabs(t - 1.0) < eps) return ans[n]; double aans = ans[n]; for(int i = n-1; i >= 0; --i){ double p0 = ans[i] / aans; double p1 = (p0-t)/(1-t); if(p0 < t) aans = (1+t) / 2 * aans; else aans = ans[i] * p1 + (p0+1)/2*aans * (1-p1); } return aans; } int main(){ ans[0] = 1.0; for(int i = 1; i < 32; ++i) ans[i] = ans[i-1] * 2.0; while(scanf("%d %lf", &n, &t) == 2){ if(!n && !t) break; printf("%.3lf\n", solve()); } return 0; }
UVa 10900 So you want to be a 2n-aire? (概率DP,数学)
标签:
原文地址:http://www.cnblogs.com/dwtfukgv/p/5746760.html