概率dp初探
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 }
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\n", fz / fm); 52 return 0; 53 }
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 }