数学期望和概率DP题目泛做(为了对应AD的课件)

题1: Uva 1636 Headshot

题目大意:

给出一个000111序列,注意实际上是环状的。问是0出现的概率大,还是当前是0,下一个还是0的概率大。

问题比较简单,注意比较大小: A/C > B/D  <=> A * D > B * C

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <iostream>
 6 
 7 using namespace std;
 8 
 9 char str[205];
10 
11 void Solve(){
12   int len = strlen(str);
13   int cnt1 = 0, cnt2 = 0;
14 
15   for(int i = 0; i < len; ++ i){
16     if(i == len - 1){
17       if(str[i] == '0') ++ cnt1;
18       if(str[i] == '0' && str[0] == '0') ++ cnt2;
19     }
20     else{
21       if(str[i] == '0') ++ cnt1;
22       if(str[i] == '0' && str[i + 1] == '0') ++ cnt2;
23     }
24   }
25 
26   if(cnt2 * len > cnt1 * cnt1) puts("SHOOT");
27   else if(cnt2 * len < cnt1 * cnt1) puts("ROTATE");
28   else puts("EQUAL");
29 }
30 
31 int main(){
32   while(scanf("%s", str) != EOF){
33     Solve();
34   }
35 
36   return 0;
37 }
Uva 1636

题2: Uva 1637 Double Patience

扑克牌拿牌问题。开一个9维的数组,记忆化搜索。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 double f[5][5][5][5][5][5][5][5][5];
 6 bool vi[5][5][5][5][5][5][5][5][5];
 7 char str[4][5], poker[10][5];
 8 
 9 double dfs(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, int p9){
10   if(vi[p1][p2][p3][p4][p5][p6][p7][p8][p9])
11     return f[p1][p2][p3][p4][p5][p6][p7][p8][p9];
12   vi[p1][p2][p3][p4][p5][p6][p7][p8][p9] = true;
13 
14   bool flag = false;
15   int top[11] = {0, p1, p2, p3, p4, p5, p6, p7, p8, p9};
16   double &x = f[p1][p2][p3][p4][p5][p6][p7][p8][p9];
17 
18   for(int i = 1; i <= 9; ++ i)
19     if(top[i]){
20       flag = true;
21       break;
22     }
23   if(!flag)
24     return x = 1.0;
25 
26   int cnt = 0;
27   double sumper = 0;
28 
29   for(int i = 1; i <= 9; ++ i){
30     if(top[i]){
31       for(int j = i + 1; j <= 9; ++ j){
32         if(top[j] && poker[i][top[i]] == poker[j][top[j]]){
33           cnt ++;
34           top[i] --; top[j] --;
35 
36           sumper += dfs(top[1], top[2], top[3], top[4], top[5], top[6], top[7], top[8], top[9]);
37 
38           top[i] ++; top[j] ++;
39         }
40       }
41     }
42   }
43 
44   if(sumper > 0) x = (double) sumper / cnt;
45 
46   return x;
47 }
48 
49 
50 int main(){
51   while(~scanf("%s%s%s%s", str[0], str[1], str[2], str[3])){
52     memset(f, 0, sizeof f);
53     memset(vi, false, sizeof vi);
54 
55     for(int i = 1; i <= 4; ++ i)
56       poker[1][i] = str[i -1][0];
57     for(int i = 1; i <= 8; ++ i){
58       scanf("%s%s%s%s", str[0], str[1], str[2], str[3]);
59       for(int j = 1; j <= 4; ++ j)
60         poker[i + 1][j] = str[j - 1][0];
61     }
62 
63     dfs(4, 4, 4, 4, 4, 4, 4, 4, 4);
64 
65     printf("%.6lf
", f[4][4][4][4][4][4][4][4][4]);
66   }
67 
68   return 0;
69 }
Uva 1637

题3:Uva 1639 Candy

题目大意:

两盒子糖,每盒中都有N个,在一个盒子中取的概率是p,另一个是1-p,求一个盒子没有糖之后另一个盒子剩的糖数的期望。

式子不难列,高中数学期望会考。但是主要是计算,组合数是极大数,概率又是极小数,计算机算的话要取对数,把大数化小,小数化大,乘法变加,

除法变减。 注意精度。不要为了简化代码新定义变量等于一长串代码中的一部分,会挂精度。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const int N = 400000 + 5;
 6 
 7 int n, cnt = 0;
 8 double p;
 9 long double fac[N];
10 
11 int main(){
12   
13   fac[1] = 0;
14   for(int i = 2; i <= 400000; ++ i)
15     fac[i] = fac[i - 1] + log(i);
16 
17   while(~scanf("%d%lf", &n, &p)){
18     double ans = 0;
19 
20     ++ cnt;
21     if(p == 0 || p == 1){
22       printf("Case %d: %.6lf
", cnt, (double) n);
23       continue;
24     }
25 
26     int U = 2 * n;
27     
28     for(int i = 0; i <= n; ++ i){
29       ans += exp(fac[U - i] - fac[n] - fac[n - i] + log(p) * (n + 1) + log(1 - p) * (n - i)) * i + exp(fac[U - i] - fac[n] - fac[n - i] + log(p) * (n - i) + log(1 - p) * (n + 1)) * i;
30     }
31 
32     printf("Case %d: %.6lf
", cnt, ans);
33   }
34 
35   return 0;
36 }
Uva 1639
原文地址:https://www.cnblogs.com/sxprovence/p/5164527.html