Code Jam 2008 APAC local onsites Problem C. Millionaire —— 概率DP

题意:

你有X元钱,进行M轮赌博游戏。每一轮可以将所持的任意一部分钱作为赌注(赌注为0元表示这一轮不押),赌注可以是小数的,不是一定要整数。每一轮 赢的概率为P,赢了赌注翻倍,输了赌注就没了。如果你最后持有至少1000000元钱的话,就可以把钱全部带走。要求计算在采取最优策略时,获得至少 1000000元钱的概率。

数据范围:

0<=P<=1

1<=X<=1000000

1<=M<=15

 

 

 1 int M , X  ;  
 2 double P;  
 3 double dp[2][(1 << 15) + 1];  
 4 void solve()  
 5 {  
 6     int n = 1 << M;  
 7     double *pre = dp[0] , *nxt = dp[1];  
 8     memset(pre , 0 , sizeof(double) * (n + 1));  
 9 ///    memset(pre , 0 , sizeof(pre)); 这样初始化是不行的,因为pre为一个double型的指针,不是整个数组。  
10     pre[n] = 1.0;  
11     for(int r = 0 ; r < M; r++)///枚举第几轮  
12     {  
13         for(int i = 0 ; i <= n ; i++)///枚举当前是哪种状态  
14         {  
15             int step = min(i , n - i);///如果step大于n / 2 , 等会儿转移的时候可能会超过n  
16             double t = 0.0;  
17             for(int j = 0 ; j <= step ; j++)///枚举当前的所有可能走法  
18             {  
19                 t = max(t , P * pre[i + j] + (1 - P) * pre[i - j]);///求出期望的最大值  
20             }  
21             nxt[i] = t;  
22         }  
23         swap(pre , nxt);///交换两个数组的值进行滚动  
24     }  
25     int i = (LL)X * n / 1000000;///找到X对应的是第几块  
26 //    for(int i = 0 ; i <= n ; i++)cout << '*' << pre[i] << endl;  
27     printf("%.6lf\n" , pre[i]);  
28 } 

 

posted @ 2015-03-28 11:26  daydaycode  阅读(945)  评论(0编辑  收藏  举报