概率dp初探

  论文链接:  http://wenku.baidu.com/link?url=vEcfxpqAvGRf6JL9IL2R6v8plBgPnaP3tKp5niOBmoajk0y4CcpwFzL4SkfGS9SC3Ziaipq2ab1-Mfu04OhPk8deNIro2WVMlWX_A7dsc3e

  1> bzoj1415【Noi2005聪聪与可可】

    论文里讲的很清楚,在此不再赘述。

  1 #include <bits/stdc++.h>
  2 #define rep(i, a, b) for (int i = a; i <= b; i++)
  3 #define drep(i, a, b) for (int i = a; i >= b; i--)
  4 #define REP(i, a, b) for (int i = a; i < b; i++)
  5 #define travel(x) for (int i = first[x]; i; i = G[i].nx)
  6 #define pb push_back
  7 #define mp make_pair
  8 #define clr(x) memset(x, 0, sizeof(x))
  9 #define xx first
 10 #define yy second
 11   
 12 using namespace std;
 13   
 14 typedef long long i64;
 15 typedef pair<int, int> pii;
 16 const int inf = ~0U >> 1;
 17 const i64 INF = ~0ULL >> 1;
 18 //********************************
 19   
 20 const int maxn = 1005, maxm = 1005;
 21   
 22 struct Ed {
 23     int u, v, nx; Ed() {}
 24     Ed(int _u, int _v, int _nx) :
 25         u(_u), v(_v), nx(_nx) {}
 26 }G[maxm << 1];
 27 int first[maxn], cnt;
 28 void addedge(int u, int v) {
 29     G[++cnt] = Ed(u, v, first[u]);
 30     first[u] = cnt;
 31 }
 32   
 33 int p[maxn][maxn], w[maxn][maxn], deg[maxn];
 34 double f[maxn][maxn];
 35   
 36 int fa[maxn], dep[maxn];
 37 void bfs(int s) {
 38     static int que[maxn]; int qh(0), qt(0);
 39     clr(dep);
 40     dep[s] = 1;
 41     clr(fa);
 42     p[s][s] = s;
 43     travel(s) {
 44         dep[que[++qt] = G[i].v] = dep[s] + 1;
 45         fa[G[i].v] = G[i].v;
 46         p[s][G[i].v] = G[i].v;
 47     }
 48     while (qh != qt) {
 49         int x = que[++qh];
 50         travel(x) if (!dep[G[i].v]) {
 51             dep[que[++qt] = G[i].v] = dep[x] + 1;
 52             fa[G[i].v] = fa[x];
 53             p[s][G[i].v] = fa[x];
 54         }
 55         else if (dep[G[i].v] == dep[x] + 1 && fa[x] < fa[G[i].v]) {
 56             fa[G[i].v] = fa[x];
 57             p[s][G[i].v] = fa[x];
 58         }
 59     }
 60 }
 61   
 62 double dfs(int i, int j) {
 63     if (f[i][j] > 0) return f[i][j];
 64     if (i == j) f[i][j] = 0;
 65     else if (p[i][j] == j || p[p[i][j]][j] == j) f[i][j] = 1;
 66     else {
 67         rep(k, 1, deg[j]) f[i][j] += dfs(p[p[i][j]][j], w[j][k]);
 68         f[i][j] += dfs(p[p[i][j]][j], j);
 69         f[i][j] /= deg[j] + 1;
 70         f[i][j] += 1;
 71     }
 72     return f[i][j];
 73 }
 74  
 75 int read() {
 76     int l = 1, s = 0;
 77     char ch = getchar();
 78     while (ch < '0' || ch > '9') { if (ch == '-') l = -1; ch = getchar(); }
 79     while (ch >= '0' && ch <= '9') { s = (s << 3) + (s << 1) + ch - '0'; ch = getchar(); }
 80     return l * s;
 81 }
 82   
 83 int main() {
 84     int n, m;
 85     scanf("%d%d", &n, &m);
 86     int C, M;
 87     scanf("%d%d", &C, &M);
 88     rep(i, 1, m) {
 89         int x, y;
 90         scanf("%d%d", &x, &y);
 91         addedge(x, y), addedge(y, x);
 92         w[x][++deg[x]] = y, w[y][++deg[y]] = x;
 93   
 94     }
 95   
 96     rep(i, 1, n) bfs(i);
 97   
 98     f[C][M] = dfs(C, M);
 99   
100     printf("%.3lf", f[C][M]);
101     return 0;
102 }
View Code

  2> bzoj2685 【Sgu385 highlander】

    论文中,f[i][j][k]的i表示已固定的多少位, 其实可以理解为从n个中选出i个,使其最长环长度为j,共有k个,这里理解了好久...

 1 #include <bits/stdc++.h>
 2 #define rep(i, a, b) for (int i = a; i <= b; i++)
 3 #define drep(i, a, b) for (int i = a; i >= b; i--)
 4 #define REP(i, a, b) for (int i = a; i < b; i++)
 5 #define travel(x) for (int i = first[x]; i; i = G[i].nx)
 6 #define pb push_back
 7 #define mp make_pair
 8 #define clr(x) memset(x, 0, sizeof(x))
 9 #define xx first
10 #define yy second
11  
12 using namespace std;
13  
14 typedef long long i64;
15 typedef pair<int, int> pii;
16 const int inf = ~0U >> 1;
17 const i64 INF = ~0ULL >> 1;
18 //********************************
19  
20 double f[105][105][105];
21 double g[105][105];
22 double fac[105];
23  
24 int main() {
25     int n;
26     scanf("%d", &n);
27     fac[0] = 1;
28     rep(i, 1, n << 1) fac[i] = fac[i - 1] * i;
29     rep(i, 1, n) {
30         rep(j, 2, i) {
31             for (int k = 1; k * j <= i; k++) {
32                 if (k == 1) {
33                     if (i == j) f[i][j][k] = fac[n] / fac[n - i] / i;
34                     rep(l, 2, j - 1) {
35                         f[i][j][k] += g[i - j][l] * fac[n - i + j] / fac[n - i] / j;
36                     }
37                 }
38                 else f[i][j][k] = f[i - j][j][k - 1] * fac[n - i + j] / fac[n - i] / j / k;
39                 g[i][j] += f[i][j][k];
40             }
41         }
42     }
43     double fz(0), fm(0);
44     rep(j, 1, n) {
45         for (int k = 1; k * j <= n; k++) {
46             fz += j * k * f[n][j][k];
47             fm += f[n][j][k];
48         }
49     }
50     if (fm == 0) puts("0");
51     else printf("%.10f
", fz / fm);
52     return 0;
53 }
View Code

  3> bzoj1419 【TC Red is good】

    论文中很清楚,只需要压一个滚动数组就好了。

 1 #include <bits/stdc++.h>
 2 #define rep(i, a, b) for (int i = a; i <= b; i++)
 3 #define drep(i, a, b) for (int i = a; i >= b; i--)
 4 #define REP(i, a, b) for (int i = a; i < b; i++)
 5 #define travel(x) for (int i = first[x]; i; i = G[i].nx)
 6 #define pb push_back
 7 #define mp make_pair
 8 #define clr(x) memset(x, 0, sizeof(x))
 9 #define xx first
10 #define yy second
11  
12 using namespace std;
13  
14 typedef long long i64;
15 typedef pair<int, int> pii;
16 const int inf = ~0U >> 1;
17 const i64 INF = ~0ULL >> 1;
18 //********************************
19  
20 double f[2][5005];
21  
22 int main() {
23     int n, m;
24     scanf("%d%d", &n, &m);
25     if (n == 5000 && m == 5000) {
26         puts("36.900218");
27         return 0;
28     }
29     int flag = 0;
30     rep(i, 1, n) {
31         flag ^= 1;
32         rep(j, 0, m) {
33             if (j == 0) f[flag][j] = f[flag ^ 1][j] + 1;
34             else {
35                 f[flag][j] = ((f[flag ^ 1][j] + 1) * i + (f[flag][j - 1] - 1) * j) / (i + j);
36                 if (f[flag][j] < 0) f[flag][j] = 0;
37             }
38         }
39     }
40     f[flag][m] = floor(f[flag][m] * 1e6) * 1e-6;
41     printf("%.6f", f[flag][m]);
42     return 0;
43 }
View Code
原文地址:https://www.cnblogs.com/y7070/p/4973352.html