zoukankan      html  css  js  c++  java
  • UESTC 1330 柱爷与远古法阵【高斯消元】

    题目链接【http://acm.uestc.edu.cn/#/problem/show/1330】

    题意:有一个长度为L(L <= 300)的长廊,有一人站在最左边,他要到最右边去,他每次可以走1 ~ 6 步,每一次走的步数是随机发生的。并且某些位置有传送门(a,b)表示a位置有个传送门,可以直接到达b,然后求出到达最右边的期望是多少?

    题解:首先,我们先列出公式,设dp[i]表示从 i 点到达最右边的期望,则1、dp[L] =0 。2、如果a有传送门b那么dp[a] = dp[b] 。否则 dp[x] = (dp[x+1]+dp[x+2] + dp[x+y])/6+1;( x + y <= L && y <= 6)。化简后就得到,6 * dp[x] - dp[x+1] - dp[x+2] - ... - dp[x+y] == 6。那么我们一共可以列出L个方程,一共有L个未知量,只要用高斯消元解出来就可以了。

    注意:1、每个点最多只有一个传送门,2、这道题存在无解的情况,3、这道题精度卡的很高。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long double LB;
    const LB eps = 1e-14;
    const int maxn = 350 + 15;
    LB a[maxn][maxn], x[maxn];
    int Guess(int equ, int var)
    {
        int i, j, k, col, max_r;
        for(k = 1, col = 1; k <= equ && col <= var; k++, col++)
        {
            max_r = k;
            for(i = k + 1; i <= equ; i++)
                if(fabs(a[i][col] ) > fabs(a[max_r][col])) max_r = i;
            if(fabs(a[max_r][col]) < eps )  return 0;//无解
            if(k != max_r)
            {
                for(j = col; j <= var; 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 <= var; j++)  a[k][j] /= a[k][col];
            a[k][col] = 1;
            for(i = 1; i <= equ; i++)
                if(i != k)
                {
                    x[i] -= x[k] * a[i][col];
                    for(j = col + 1; j <= var; j++) a[i][j] -= a[k][j] * a[i][col];
                    a[i][col] = 0;
                }
        }
        return 1;
    }
    int N, M;
    int f[maxn];//表示某点有没有传送门
    int main ()
    {
        scanf("%d %d", &N, &M);
        memset(a, 0, sizeof(a));
        for(int i = 1; i <= N; i++) f[i] = 0;
        for(int i = 1; i <= M; i++)
        {
            int u, v;
            scanf("%d %d", &u, &v);
            f[u] = v;
        }
        for(int i = 1; i < N; i++)
        {
            a[i][i] = 6.0;
            if(f[i])
            {
                a[i][f[i]] = -6.0;
                continue;
            }
            x[i] = 6.0;
            for(int j = 1; j <= 6; j++)
            {
                if(i + j <= N) a[i][i + j] -= 1.0;
                else a[i][i] -= 1.0;
            }
        }
        a[N][N] = 1.0, x[N] = 0;
        if(!Guess(N, N)) printf("-1
    ");
        else printf("%.12Lf
    ", x[1]);
        return 0;
    }
    

      

  • 相关阅读:
    golang:bson.ObjectId与string转化
    Go语言的序列化与反序列化(gob)
    Go语言使用匿名结构体解析JSON数据
    Java课程设计---创建数据库工具类
    Java课程设计---实现登录(1)
    Java课程设计---新建项目及导入如何jar包
    Java课程设计---Eclipse基本环境配置
    Java课程设计---WindowBuilder插件安装
    Spring简单介绍
    【软件工程】简单考试题
  • 原文地址:https://www.cnblogs.com/pealicx/p/7603493.html
Copyright © 2011-2022 走看看