标签:dp
2 4 2 0 1 0 50 50 4 1 0 2 1 100
8.14 2.00
Statistic | Submit | Discuss | Note
很明显的概率dp,设dp[i]表示在点i的时候达到终点的期望步数
dp[i] = p1 * (dp[i + 1] + 1) + p2 * (dp[i + 2] + 2) + ...+ pm * (dp[i + m] + m);
当然 dp[e] = 0;
但是由于方向有2个,所以我们要把反着走的状态变成正着走,也就是把路对称一下, 012345 -》 0123456789
这样 比如 4 走到 3就变成了6走到7,方向就固定了,然后就可以建立线性方程组求解了,注意有些点到不了,这个得先用bfs处理一下,顺便给每一个可到的点编号,然后高斯消元就行了
/************************************************************************* > File Name: hdu4418.cpp > Author: ALex > Mail: 405045132@qq.com > Created Time: 2014年12月29日 星期一 17时01分42秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 210; const double eps = 1e-12; double sum_p; double mat[N][N], x[N]; double p[N]; bool free_x[N]; int ord[N]; int n, m, s, e, cnt; int Gauss() { int col, k, equ, var, max_r; int free_index, free_num; equ = cnt; var = cnt; k = col = 0; for (int i = 0; i < var; ++i) { free_x[i] = true; x[i] = 0; } for (; k < equ && col < var; ++k, ++col) { max_r = k; for (int i = k + 1; i < equ; ++i) { if (fabs(mat[i][col]) - fabs(mat[max_r][col]) > eps) { max_r = i; } } if (max_r != k) { for (int j = k; j < var + 1; ++j) { swap(mat[k][j], mat[max_r][j]); } } if (fabs(mat[k][col]) <= eps) { --k; continue; } for (int i = k + 1; i < equ; ++i) { double tmp = mat[i][col] / mat[k][col]; for (int j = col; j < var + 1; ++j) { mat[i][j] -= tmp * mat[k][j]; } } } //判断解的情况 for (int i = k; i < equ; ++i) { if (fabs(mat[i][var]) > eps) { return 0; } } if (k < var) { for (int i = k - 1; i >= 0; --i) { free_num = 0; for (int j = 0; j < var; ++j) { if (fabs(mat[i][j]) > eps && free_x[j]) { free_num++; free_index = j; } } if (free_num > 1) { continue; } double tmp = mat[i][var]; for (int j = 0; j < var; ++j) { if (fabs(mat[i][j]) > eps && j != free_index) { tmp -= mat[i][j] * x[j]; } } free_x[free_index] = false; x[free_index] = tmp / mat[i][free_index]; } return var - k; } for (int i = var - 1; i >= 0; --i) { double tmp = mat[i][var]; for (int j = i + 1; j < var; ++j) { if (fabs(mat[i][j]) > eps) { tmp -= x[j] * mat[i][j]; } } x[i] = tmp / mat[i][i]; } return 1; } void bfs() { cnt = 0; queue <int> qu; memset (ord, -1, sizeof(ord)); ord[s] = cnt++; while (!qu.empty()) { qu.pop(); } qu.push(s); while (!qu.empty()) { int u = qu.front(); qu.pop(); for (int i = 1; i <= m; ++i) { if (p[i] <= eps) { continue; } int v = (i + u) % n; if (ord[v] == -1) { ord[v] = cnt++; qu.push(v); } } } } void build() { for (int i = 0; i < n; ++i) { if (ord[i] == -1) { continue; } if (i == e || i == (n - e) % n) { mat[ord[i]][ord[i]] = 1; mat[ord[i]][cnt] = 0; continue; } mat[ord[i]][ord[i]] = 1.0; for (int j = 1; j <= m; ++j) { if (ord[(i + j) % n] == -1) { continue; } mat[ord[i]][ord[(i + j) % n]] -= p[j]; } mat[ord[i]][cnt] = sum_p; } } int main() { int t, D; scanf("%d", &t); while (t--) { sum_p = 0; memset (mat, 0, sizeof(mat)); scanf("%d%d%d%d%d", &n, &m, &e, &s, &D); n = 2 * n - 2; for (int i = 1; i <= m; ++i) { scanf("%lf", &p[i]); p[i] /= 100.0; sum_p += i * p[i]; } if (s == e || n == 1) { printf("0.00\n"); continue; } if (D > 0) { s = (n - s) % n; } bfs(); if (ord[e] == -1 && ord[(n - e) % n] == -1) { printf("Impossible !\n"); continue; } build(); if (!Gauss()) { printf("Impossible !\n"); continue; } printf("%.2f\n", x[ord[s]]); } return 0; }
标签:dp
原文地址:http://blog.csdn.net/guard_mine/article/details/42242499