zoukankan      html  css  js  c++  java
  • HDU4418 Time travel(期望dp 高斯消元)

    题意

    题目链接

    Sol

    mdzz这题真的太恶心了。。

    首先不难看出这就是个高斯消元解方程的板子题

    (f[x] = sum_{i = 1}^n f[to(x + i)] * p[i] + ave)

    (ave)表示每次走的期望路程

    然后一件很恶心的事情是可以来回走,而且会出现(M > N)的情况(因为这个调了两个小时。。)

    一种简单的解决方法是在原序列的后面接一段翻转后的序列

    比如(1 2 3 4)可以写成(1 2 3 4 3 2)

    然后列式子解方程就行了

    附送一个数据生成器

    #include<bits/stdc++.h>
    using namespace std;
    int main() {
        freopen("a.in", "w", stdout);
        srand((unsigned)time(NULL));
        int T = 30;
        printf("%d
    ", T);
        while(T--) {
            int N = rand() % 100 + 1, M = rand() % 20 + 1, Y = rand() % N, X = rand() % N, D = rand() % 2;
            if(X == 0 || X == N - 1) D = -1;
            printf("%d %d %d %d %d
    ", N, M, Y, X, D);
            int res = 100;
            for(int i = 1; i <= M - 1; i++) {
                int rd;
                if(res == 0) rd = 0;
                else rd = rand() % res + 1;
                printf("%d ", rd); res -= rd;
            }
            printf("%d
    ", res);
        }
        return 0;
    }
    
    #include<bits/stdc++.h> 
    #define LL long long 
    using namespace std;
    const int MAXN = 1001, mod = 998244353;
    const double eps = 1e-9;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int N, M, X, Y, D, Lim, vis[MAXN];
    double g[MAXN][MAXN], p[MAXN], ave;
    int Gauss() {
        for(int i = 1; i < Lim; i++) {
            int mx = i;
            for(int j = i + 1; j < Lim; j++) 
                if(fabs(g[j][i]) > fabs(g[mx][i])) mx = j;
            swap(g[i], g[mx]);
            //assert(g[i][i] > eps);
            if(fabs(g[i][i]) < eps) return -1;
            for(int j = i + 1; j < Lim; j++) {
                double p = g[j][i] / g[i][i];
                for(int k = i + 1; k <= Lim; k++) 
                    g[j][k] -= g[i][k] * p;
            }
        }   
        for(int i = 1; i < Lim; i++) if(fabs(g[i][i]) < eps) return -1;
        for(int i = Lim - 1; i >= 1; i--) {
            g[i][i] = g[i][Lim] / g[i][i];
            for(int j = i - 1; j >= 1; j--)
                g[j][Lim] -= g[j][i] * g[i][i], g[j][i] = 0;
        }
    }
    int walk(int a, int b) { 
        b %= (Lim - 1);
        int x = a + b;
        if(x <= Lim - 1) return x;
        return x % (Lim - 1);
    }
    void init() {
        memset(g, 0, sizeof(g));
        memset(vis, 0, sizeof(vis));
        ave = 0;
    }
    void BFS() {
        queue<int> q; q.push(X); vis[X] = 1;
        while(!q.empty()) {
            int x = q.front(); q.pop();
            for(int i = 1; i <= M; i++) {
                if(p[i] > eps) {
                    int t = walk(x, i);
                    if(!vis[t]) q.push(t), vis[t] = 1;
                }
            }
        }
    }
    void solve() {
        init();
        N = read(); M = read(); Y = read() + 1; X = read() + 1; D = read();
        Lim = (N << 1) - 1;
        for(int i = 1; i <= M; i++) p[i] = (double) read() / 100, ave += (double) i * p[i];
        if(X == Y) {puts("0.00"); return;}
        if(D > 0 || (D == -1 && X > Y)) X = N - X + 1, Y = N - Y + 1;
        BFS();
        for(int i = 1; i <= 2 * N - 2; i++) {
            g[i][i] = 1; 
            if(!vis[i]) {g[i][Lim] = 3e18; continue;}
            if(i == Y || (Lim - i + 1 == Y)) continue;
            g[i][Lim] = ave;
            for(int j = 1, t; j <= M; j++) {
                t = walk(i, j);
                g[i][t] -= p[j];
            }
        }
        if((!vis[Y] && !vis[Lim - Y + 1]) || (Gauss() == -1)) puts("Impossible !");
        else printf("%.2lf
    ", g[X][X]);
    }
    int main() {
        //freopen("a.in", "r", stdin);
        //freopen("b.out", "w", stdout);
        for(int T = read(); T; T--, solve());
        return 0;
    }
    
  • 相关阅读:
    字符串案例1
    字符串1
    标准类制作
    构造方法
    封装
    成员变量和局部变量
    类和对象的案例

    案例
    方法的参数传递
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/10209425.html
Copyright © 2011-2022 走看看