POJ3744(概率dp)
思路:一长段概率乘过去最后会趋于平稳,所以因为地雷只有10个,可以疯狂压缩其位置,这样就不需要矩阵乘优化了。另外初始化f[0] = 0, f[1] = 1,相当于从1开始走吧。双倍经验:洛谷1052.
1 for (int i = 1; i <= n; i++) { 2 if (pos[i] - pos[i - 1] > 50) { 3 for (int j = n; j >= i; j--) 4 pos[j] -= (pos[i] - pos[i - 1] - 50); 5 } 6 }
这段代码j要倒着写否则先从i开始的话pos[i] - pos[i-1]就变了,我tm居然WA了一板一上午……请叫我绝世大傻逼。
非矩阵版:
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 typedef double db; 8 9 const int maxn = 1e3 + 5; 10 int n, pos[20]; 11 db f[maxn]; 12 db p; 13 14 db solve() { 15 memset(f, 0, sizeof f); 16 f[1] = 1.0; 17 int t = 1; 18 for (int i = 1; i <= pos[n]; i++) { 19 if (i == pos[t]) f[i] = 0, t++; 20 f[i + 1] += p * f[i]; 21 f[i + 2] += (1.0 - p) * f[i]; 22 } 23 return f[pos[n] + 1]; 24 } 25 26 int main() { 27 while (scanf("%d%lf", &n, &p) != EOF) { 28 for (int i = 1; i <= n; i++) scanf("%d", &pos[i]); 29 sort(pos + 1, pos + 1 + n); 30 for (int i = 1; i <= n; i++) { 31 if (pos[i] - pos[i - 1] > 50) { 32 for (int j = n; j >= i; j--) 33 pos[j] -= (pos[i] - pos[i - 1] - 50); 34 } 35 } 36 printf("%.7f\n", solve()); 37 } 38 return 0; 39 }
顺手练一下矩阵,写得low了点:
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <ctime> 7 #include <cctype> 8 #include <climits> 9 #include <iostream> 10 #include <iomanip> 11 #include <algorithm> 12 #include <string> 13 #include <sstream> 14 #include <stack> 15 #include <queue> 16 #include <set> 17 #include <map> 18 #include <vector> 19 #include <list> 20 #include <fstream> 21 #include <bitset> 22 #define init(a, b) memset(a, b, sizeof(a)) 23 #define rep(i, a, b) for (int i = a; i <= b; i++) 24 #define irep(i, a, b) for (int i = a; i >= b; i--) 25 using namespace std; 26 27 typedef double db; 28 typedef long long ll; 29 typedef unsigned long long ull; 30 typedef pair<int, int> P; 31 const int inf = 0x3f3f3f3f; 32 const ll INF = 1e18; 33 34 template <typename T> void read(T &x) { 35 x = 0; 36 int s = 1, c = getchar(); 37 for (; !isdigit(c); c = getchar()) 38 if (c == '-') s = -1; 39 for (; isdigit(c); c = getchar()) 40 x = x * 10 + c - 48; 41 x *= s; 42 } 43 44 template <typename T> void write(T x) { 45 if (x < 0) x = -x, putchar('-'); 46 if (x > 9) write(x / 10); 47 putchar(x % 10 + '0'); 48 } 49 50 template <typename T> void writeln(T x) { 51 write(x); 52 puts(""); 53 } 54 55 struct Matrix { 56 db v[2][2]; 57 58 Matrix() { 59 init(v, 0); 60 } 61 62 friend Matrix operator * (Matrix A, Matrix B) { 63 Matrix ret; 64 rep(i, 0, 1) rep(j, 0, 1) rep(k, 0, 1) 65 ret.v[i][j] += A.v[i][k] * B.v[k][j]; 66 return ret; 67 } 68 69 friend Matrix operator ^ (Matrix A, int k) { 70 Matrix ret; 71 ret.v[0][0] = ret.v[1][1] = 1; 72 for (; k; k >>= 1) { 73 if (k & 1) ret = ret * A; 74 A = A * A; 75 } 76 return ret; 77 } 78 }; 79 80 int n, pos[15]; 81 db p; 82 83 int main() { 84 while (~scanf("%d%lf", &n, &p)) { 85 rep(i, 1, n) read(pos[i]); 86 sort(pos + 1, pos + 1 + n); 87 88 pos[0] = 1, pos[n + 1] = pos[n] + 1; 89 Matrix f, dp; 90 f.v[0][0] = 1; 91 rep(i, 1, n + 1) { 92 int t = pos[i] - pos[i - 1]; 93 dp.v[0][0] = p, dp.v[1][0] = 1 - p, dp.v[0][1] = 1, dp.v[1][1] = 0; 94 f = f * (dp ^ t); 95 if (i <= n) f.v[0][0] = 0; 96 } 97 98 printf("%.7f\n", f.v[0][0]); 99 } 100 return 0; 101 }