概率dp求期望,高斯消元解多元式
直接套模板
#include <CSTDIO> #include <QUEUE> using namespace std; // hdu 4118 // http://www.cnblogs.com/kuangbin/archive/2012/10/02/2710606.html /* 高斯消元 求期望 e[x] = Σ(e[(x+i)%n]+i)*p[i] e[x] - p1*e[x+1] - p2*e[x+2] - p3*e[x+3] - ... - pm*e[x+m] = p1*1 + p2*2 + p3*3 + ... + pm*m */ const int MAXN = 250; const double _inf = 1e-9; double a[MAXN][MAXN], x[MAXN]; // 方程左边的矩阵和等式右边的值, x存放最后结果 int equ, val; // 方程数 未知数个数 inline double mabs(double _X) { return _X<0?-_X:_X; } int gauss() { int i,j,k,col,max_r; for(k=0,col=0;k<equ&&col<val;k++,col++) { max_r=k; for(i=k+1;i<equ;i++) if(mabs(a[i][col])>mabs(a[max_r][col])) max_r=i; if(mabs(a[max_r][col])<_inf) return 0; if(k!=max_r) { for(j=col;j<val;j++) swap(a[k][j],a[max_r][j]); swap(x[k],x[max_r]); } x[k]/=a[k][col]; for(j=col+1;j<val;j++)a[k][j]/=a[k][col]; a[k][col]=1; for(i=0;i<equ;i++) if(i!=k) { x[i]-=x[k]*a[i][k]; for(j=col+1;j<val;j++)a[i][j]-=a[k][j]*a[i][col]; a[i][col]=0; } } return 1; } int n, m, _n; double p[MAXN]; int num[MAXN], cnt; void bfs(int s) { memset(num, -1, sizeof num); queue<int> q; cnt = 0; num[s] = cnt++; q.push(s); int t, i; while (!q.empty()) { t = q.front(); q.pop(); for ( i = 1; i<= m; ++i) { if ( mabs(p[i] < _inf)) continue; int tmp = (t+i)%n; if ( num[tmp] == -1) { num[tmp] = cnt++; q.push(tmp); } } } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif int t, i, j, k;; int s, e, d; scanf("%d", &t); while (t--) { scanf("%d%d%d%d%d", &_n, &m, &e, &s, &d); for (i = 1; i<= m; i++) scanf("%lf", p+i), p[i]/=100.0; if ( e == s) {printf("0.00\n"); continue;} n = _n * 2 - 2; // 翻转 0 1 2 3 2 1 0 if (d == 1) s = n - s; // 始终保持正向向右 bfs(s); if (num[e] == -1 && num[n-e] == -1) // 排除不可能达到的点 { printf("Impossible !\n" ); continue; } equ = val = cnt; memset(a, 0, sizeof a); memset(x, 0, sizeof x); for (i = 0; i< n; ++i) { if (num[i] != -1) { if (i == e || i == n-e) { a[num[i]][num[i]] = 1; x[num[i]] = 0; continue; } a[num[i]][num[i]] = 1; for (j = 1; j<= m; ++j) { k = (i+j)%n; if (num[k] != -1) { a[num[i]][num[k]] -= p[j]; x[num[i]] += j*p[j]; } } } } if (gauss()) printf("%.2lf\n", x[num[s]]); else printf("Impossible !\n" ); } return 0; }