zoukankan      html  css  js  c++  java
  • HDU 4418 Time travel

    Time travel

    http://acm.hdu.edu.cn/showproblem.php?pid=4418

    分析:

      因为走到最后在折返,可以将区间复制一份,就变成了只往右走,012343210。

      写出转移方程:

    $f[t] = 0$

    $f[i] = p_1 imes (f[i +1] + 1) + p_2 imes (f[i +2] + 2) + cdots$

    $ =sumlimits_{j=1}^{m}p_j imes (f[i + j] + j) $

    $= sumlimits_{j=1}^{m}p_j imes f[i + j] + sumlimits_{j=1}^{m}p_j imes j$

    然后列出线性方程组,用高斯消元求解。

    $f[i] = sumlimits_{j=1}^{m}p_j imes f[i + j] + sumlimits_{j=1}^{m}p_j imes j$

    $sumlimits_{j=1}^{m}p_j imes j = f[i] - sumlimits_{j=1}^{m}p_j imes f[i + j]$

    补上其他项就是:

    $sum =0 imes f[0] +0 imes f[1] + cdots + f[i] + p_1 imes f[i+1] + p_2 imes f[i+2] + cdots +0 imes f[n-1] + 0 imes f[n]$

    首先bfs判一下能不能到达这个点。

    代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<cctype>
     7 #include<set>
     8 #include<vector>
     9 #include<queue>
    10 #include<map>
    11 using namespace std;
    12 typedef long long LL;
    13 
    14 inline int read() {
    15     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    16     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    17 }
    18 const int N = 505;
    19 const double eps = 1e-9;
    20 double A[N][N], p[N], sum;
    21 bool vis[N];
    22 int n, m, s, t;
    23 int q[N];
    24 
    25 bool bfs() {
    26     memset(vis, false, sizeof(vis));
    27     int L = 1, R = 0;
    28     vis[s] = 1;
    29     q[++R] = s;
    30     while (L <= R) {
    31         int u = q[L ++];
    32         for (int i=1; i<=m; ++i) {
    33             int v = (u + i) % n;
    34             if (!vis[v] && fabs(p[i]) > eps) vis[v] = 1, q[++R] = v;
    35         }
    36     }
    37     return vis[t] || vis[n - t]; // n-t折叠后的另一侧的点 
    38 }
    39 void build() {
    40     memset(A, 0, sizeof(A));
    41     for (int i=0; i<n; ++i) {
    42         A[i][i] += 1;
    43         if (!vis[i]) { A[i][n] = 1e9; continue;}
    44         if (i == t || i == n - t) { A[i][n] = 0; continue; }
    45         A[i][n] = sum;
    46         for (int j=1; j<=m; ++j) 
    47             A[i][(i + j) % n] -= p[j];
    48     }
    49 }
    50 void Gauss() {
    51     for (int k=0; k<n; ++k) {
    52         int r = k;
    53         for (int i=k+1; i<n; ++i) 
    54             if (fabs(A[i][k]) > fabs(A[r][k])) r = i;
    55         if (k != r) for (int j=k; j<n; ++j) swap(A[k][j], A[r][j]);
    56         for (int i=k+1; i<n; ++i) {
    57             if (fabs(A[i][k]) > eps) {
    58                 double t = A[i][k] / A[k][k];
    59                 for (int j=k+1; j<=n; ++j) A[i][j] -= t * A[k][j]; //小于等于n 
    60             }
    61         }    
    62     }
    63     for (int i=n-1; i>=0; --i) {
    64         for (int j=i+1; j<=n; ++j) 
    65             A[i][n] -= A[j][n] * A[i][j];
    66         A[i][n] /= A[i][i];
    67     }
    68     printf("%.2lf
    ",A[s][n]);
    69 }
    70 int main() {
    71     int T, d; 
    72     scanf("%d",&T);
    73     while (T--) {
    74         scanf("%d%d%d%d%d",&n, &m, &t, &s, &d);
    75         n = (n - 1) << 1;
    76         sum = 0;
    77         for (int i=1; i<=m; ++i) {
    78             scanf("%lf",&p[i]);
    79             p[i] = p[i] / 100.0;
    80             sum += p[i] * i;
    81         }
    82         if (s == t) { puts("0.00");continue; }
    83         if (d) s = (n - s) % n;
    84         if (!bfs()) { puts("Impossible !"); continue;}
    85         build();
    86         Gauss();
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    c++ 单例模式
    c++ 时间格式化
    c++ read
    c++ 时间与字符串转换
    c++ switch case
    HIVE Transform using 用法
    python安装模块
    pip install psutil出错-You are using pip version 10.0.1, however version 18.0 is available.
    centos下安装Loadrunner
    svn-checkout后,循环遍历查找包含某字符串的文件
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9641573.html
Copyright © 2011-2022 走看看