• 【HDOJ】4418 Time travel


    1. 题目描述
    K沿着$0,1,2,cdots,n-1,n-2,n-3,cdots,1,$的循环节不断地访问$[0, n-1]$个时光结点。某时刻,时光机故障,这导致K必须持续访问时间结点。故障发生在结点x处,方向为d,
    在访问k个结点后时光机以概率$P_k%$的概率修复好,k不超过m。求当K最终访问结点Y时经过的时光结点的期望。

    2. 基本思路
    上述循环节包含包含$nn = 2n-2个$元素(因此,尤其需要特判n=1的情况,否则除0wa)。
    通过x和方向d可以唯一的确定x在这个循环节中的位置。
    设$E[i], i in [0, nn)$表示由结点i最终访问成功Y的期望。对期望进行推导
    egin{align}
        E[0] &= (E[(0+1) \% nn]+1) imes P_1 + (E[(0+2) \% nn] + 2) imes P_2 + cdots (E[(0+m) \% nn] + m) imes P_m otag \
        E[1] &= (E[(1+1) \% nn]+1) imes P_1 + (E[(1+2) \% nn] + 2) imes P_2 + cdots (E[(1+m) \% nn] + m) imes P_m otag \
            &cdots otag \
        E[i] &= (E[(i+1) \% nn]+1) imes P_1 + (E[(i+2) \% nn] + 2) imes P_2 + cdots (E[(i+m) \% nn] + m) imes P_m \
        E[i] &= 0, quad if quad id[i]=y
    end{align}
    这里显然是一个nn元方程组,可以高斯消元解。
    这题对精度有限制,因此最开始加入一个bfs,判定x能否走到y,这里一定要判定$P_j, j in [1,m]$是否近似于0。

    3. 代码

      1 /* 4418 */
      2 #include <iostream>
      3 #include <sstream>
      4 #include <string>
      5 #include <map>
      6 #include <queue>
      7 #include <set>
      8 #include <stack>
      9 #include <vector>
     10 #include <deque>
     11 #include <bitset>
     12 #include <algorithm>
     13 #include <cstdio>
     14 #include <cmath>
     15 #include <ctime>
     16 #include <cstring>
     17 #include <climits>
     18 #include <cctype>
     19 #include <cassert>
     20 #include <functional>
     21 #include <iterator>
     22 #include <iomanip>
     23 using namespace std;
     24 //#pragma comment(linker,"/STACK:102400000,1024000")
     25 
     26 #define sti                set<int>
     27 #define stpii            set<pair<int, int> >
     28 #define mpii            map<int,int>
     29 #define vi                vector<int>
     30 #define pii                pair<int,int>
     31 #define vpii            vector<pair<int,int> >
     32 #define rep(i, a, n)     for (int i=a;i<n;++i)
     33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
     34 #define clr                clear
     35 #define pb                 push_back
     36 #define mp                 make_pair
     37 #define fir                first
     38 #define sec                second
     39 #define all(x)             (x).begin(),(x).end()
     40 #define SZ(x)             ((int)(x).size())
     41 #define lson            l, mid, rt<<1
     42 #define rson            mid+1, r, rt<<1|1
     43 
     44 const int maxn = 220;
     45 typedef double mat[maxn][maxn];
     46 
     47 const double eps = 1e-8;
     48 int n, nn, m, x, y, d;
     49 int visit[maxn];
     50 int id[maxn];
     51 double P[maxn];
     52 mat g;
     53 
     54 bool gauss_elimination(int n) {
     55     int r;
     56     
     57     rep(i, 0, n) {
     58         r = i;
     59         rep(j, i+1, n) {
     60             if (fabs(g[j][i]) > fabs(g[r][i]))
     61                 r = j;
     62         }
     63         
     64         if (r != i) {
     65             rep(j, 0, n+1)
     66                 swap(g[r][j], g[i][j]);
     67         }
     68         
     69         if (fabs(g[i][i]) < eps)
     70             return false;
     71         
     72         rep(k, i+1, n) {
     73             double t = g[k][i] / g[i][i];
     74             rep(j, i+1, n+1)
     75                 g[k][j] -= t * g[i][j];
     76         }
     77     }
     78     
     79     per(i, 0, n) {
     80         rep(j, i+1, n)
     81             g[i][n] -= g[i][j] * g[j][n];
     82         g[i][n] /= g[i][i];
     83     }
     84     
     85     return true;
     86 }
     87 
     88 int bfs(int bx) {
     89     queue<int> Q;
     90     int p = 0;
     91     bool ret = false;
     92     
     93     memset(visit, -1, sizeof(visit));
     94     visit[bx] = p++;
     95     Q.push(bx);
     96     
     97     while (!Q.empty()) {
     98         int u = Q.front();
     99         Q.pop();
    100         if (id[u] == y)
    101             ret = true;
    102         rep(j, 1, m+1) {
    103             if (fabs(P[j]) < eps)
    104                 continue;
    105             int v = (u + j) % nn;
    106             if (visit[v] == -1) {
    107                 visit[v] = p++;
    108                 Q.push(v);
    109             }
    110         }
    111     }
    112     
    113     return ret ? p : 0;
    114 }
    115 
    116 void solve() {
    117     if (x == y) {
    118         puts("0.00");
    119         return ;
    120     }
    121     
    122     nn = n*2-2;
    123     
    124     rep(i, 0, n)
    125         id[i] = i;
    126     for (int i=n,j=n-2; i<nn; ++i,--j)
    127         id[i] = j;
    128     
    129     int bx;
    130     
    131     if (d == 0)
    132         bx = x;
    133     else if (d == 1)
    134         bx = nn - x;
    135     else
    136         bx = x;
    137     
    138     int vn = bfs(bx);
    139     if (!vn) {
    140         puts("Impossible !");
    141         return ;
    142     }
    143     
    144     memset(g, 0, sizeof(g));
    145     rep(i, 0, nn) {
    146         if (visit[i] == -1)
    147             continue;
    148         
    149         int p = visit[i];
    150         g[p][p] = 1;
    151         
    152         if (id[i] == y)
    153             continue;
    154         
    155         rep(j, 1, m+1) {
    156             int k = visit[(i + j) % nn];
    157             if (k == -1)
    158                 continue;
    159             
    160             g[p][k] -= P[j];
    161             g[p][vn] += j * P[j];
    162         }
    163     }
    164     
    165     bool flag = gauss_elimination(vn);
    166     
    167     if (!flag || fabs(g[0][vn])<eps) {
    168         puts("Impossible !");
    169         return ;
    170     }
    171     
    172     printf("%.2lf
    ", g[0][vn]);
    173 }
    174 
    175 int main() {
    176     ios::sync_with_stdio(false);
    177     #ifndef ONLINE_JUDGE
    178         freopen("data.in", "r", stdin);
    179         freopen("data.out", "w", stdout);
    180     #endif
    181     
    182     int t;
    183     
    184     scanf("%d", &t);
    185     while (t--) {
    186         scanf("%d%d%d%d%d", &n,&m,&y,&x,&d);
    187         rep(i, 1, m+1) {
    188             scanf("%lf", &P[i]);
    189             P[i] /= 100.0;
    190         }
    191         solve();
    192     }
    193     
    194     #ifndef ONLINE_JUDGE
    195         printf("time = %d.
    ", (int)clock());
    196     #endif
    197     
    198     return 0;
    199 }


    4. 数据生成器

     1 import sys
     2 import string
     3 from random import randint
     4 
     5     
     6 def GenData(fileName):
     7     with open(fileName, "w") as fout:
     8         t = 20
     9         for tt in xrange(t):
    10             n = randint(1, 100)
    11             m = randint(1, 100)
    12             y = randint(0, n-1)
    13             x = randint(0, n-1)
    14             if x==0 or x==n-1:
    15                 d = -1
    16             else:
    17                 d = randint(0, 1)
    18             fout.write("%d %d %d %d %d
    " % (n, m, y, x, d))
    19             L = [0] * m
    20             tot = 0
    21             for i in xrange(m-1):
    22                 x = randint(0, 100-tot)
    23                 L[i] = x
    24                 tot += x
    25             L[m-1] = 100 - tot
    26             fout.write(" ".join(map(str, L)) + "
    ")
    27                 
    28         
    29 def MovData(srcFileName, desFileName):
    30     with open(srcFileName, "r") as fin:
    31         lines = fin.readlines()
    32     with open(desFileName, "w") as fout:
    33         fout.write("".join(lines))
    34 
    35         
    36 def CompData():
    37     print "comp"
    38     srcFileName = "F:Qt_prjhdojdata.out"
    39     desFileName = "F:workspacecpp_hdojdata.out"
    40     srcLines = []
    41     desLines = []
    42     with open(srcFileName, "r") as fin:
    43         srcLines = fin.readlines()
    44     with open(desFileName, "r") as fin:
    45         desLines = fin.readlines()
    46     n = min(len(srcLines), len(desLines))-1
    47     for i in xrange(n):
    48         ans2 = int(desLines[i])
    49         ans1 = int(srcLines[i])
    50         if ans1 > ans2:
    51             print "%d: wrong" % i
    52 
    53             
    54 if __name__ == "__main__":
    55     srcFileName = "F:Qt_prjhdojdata.in"
    56     desFileName = "F:workspacecpp_hdojdata.in"
    57     GenData(srcFileName)
    58     MovData(srcFileName, desFileName)
    59     
  • 相关阅读:
    linux异步信号handle浅析
    数据库的基本操作增删改查
    POJ1789Truck History最小生成树两种做法(Kruskal+Prim)模板题
    POJ1113Wall求凸包周长
    POJ3565AntsKM变形
    HDU2150Pipe判断线段是否相交
    POJ1815Friendship最大流最小割点+拆点+枚举
    HDU3081 Marriage Match II 最大匹配+并查集+匈牙利算法
    POJ3348Cows求凸包面积
    HDU3277Marriage Match III并查集+二分+最大流
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5243797.html
Copyright © 2020-2023  润新知