hdu 4418 Time travel

高斯消元 求期望

题意:数轴上有0~n-1 个点,你每次可能走k步,1<=k<=m ,概率为Pk。起点和终点和初始方向都输入。每次走到端点就转向。求到达终点走过路程的期望。

解法:为了方便处理转向,把n个点变成n=2*(n-2)个点。即0 1 2 3变成 0 1 2 3 2 1。确定好方向后,就可以直接列方程,设以pos为起点到达t经过的路程的期望为e[pos]。则有e[pos]=sigma(e[(pos+i)%k+i)*p[i] ,初始值显然为e[t]=e[(n-t)%n]=0。然后高斯消元解方程组即可,矩阵为n*(n+1)的矩阵。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#define eps 1e-8
#define INF 1e9
using namespace std;

double P[500] ;
int vis[500] ;
int n,m,y,x,d ,t ;
double a[500][500] ;
inline int sgn(double dd) {
    if (fabs(dd)<eps) return 0;
    return dd>0?1:-1;
}

bool bfs(int s)
{
    queue <int> que ;
    que.push(s) ;
    memset(vis, 0, sizeof vis);
    vis[s] = 1;
    while(!que.empty()){
        int d=que.front() ;
        que.pop() ;
        for(int i=1;i<=m;i++){
            if(sgn(P[i])){
                if(!vis[(d+i)%n]){
                    vis[(d+i)%n]=1;
                    que.push((d+i)%n) ;
                }

            }
        }
    }
    if(vis[y] || vis[(n-y)%n]) return 1;
    return 0;
}

int gauss(int N, int M) {
    int i, j, r, c, pvt;
    double maxp;
    for (r=0, c=0; r<N && c<M; ++r, ++c) {
        for (maxp=0, i=r; i < N; ++i)
            if (fabs(a[i][c])>fabs(maxp)) maxp = a[pvt=i][c];
        if (sgn(maxp)==0) {
            r--;
            continue;
        }
        if (pvt != r)
            for (j = r; j <= M; ++j) swap(a[r][j], a[pvt][j]);
        for (j = c+1; j <= M; ++j) {
            a[r][j] /= maxp;
            for (i = r+1; i < N; ++i)
                a[i][j] -= a[i][c]*a[r][j];
        }
    }
    for (i = r; i < N; ++i)
        if (sgn(a[i][M])) return -1;
    if (r < M) return M-r;
    for (i = M-1; i >= 0; --i)
        for (j = i+1; j < M; ++j)
            a[i][M] -= a[j][M]*a[i][j];
    return 0;
}
int main()
{

    scanf("%d",&t) ;
    while(t--){
        memset(vis, 0 , sizeof vis) ;
        scanf("%d%d%d%d%d",&n,&m,&y,&x,&d);
        for(int i=1;i<=m;i++){
            cin>>P[i] ;
            P[i]/=100;
        }
        n=(n-1) * 2;
        if(d>0) x=(n-x) % n;
        if(x==y){
            printf("0.00\n");
            continue ;
        }
        if(!bfs(x)){
            printf("Impossible !\n") ;
            continue ;
        }
        //ап╥╫Ёл
        memset(a,0,sizeof a);
        double sum=0.0 ;
        for(int i=1;i<=m ; i++){
            sum+=P[i]*i ;
        }
        for(int i=0;i<n;i++){
            a[i][i]=1;
            if(!vis[i]){
                a[i][n] = INF;
                continue ;
            }
            if(i==y || (n-y)%n == i){
                a[i][n]=0.0 ;
                continue ;
            }
            a[i][n]=sum;
            int pos= i;
            for(int j=1;j<=m;j++){

                pos=(pos+1)%n;
                a[i][pos]-=P[j];
            }
        }
        if(!gauss(n,n)){
            printf("%.2f\n",a[x][n]);
        }
        else printf("Impossible !\n");
    }

    return 0;
}
时间: 2024-08-04 15:01:11

hdu 4418 Time travel的相关文章

hdu 4418 Time travel (概率dp 细节好多)

Time travel Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1366    Accepted Submission(s): 303 Problem Description Agent K is one of the greatest agents in a secret organization called Men in

【期望DP+高斯消元】 HDU 4418 Time travel

通道 题意:1个人在数轴上来回走,以pi的概率走i步i∈[1, m],给定n(数轴长度),m,e(终点),s(起点),d(方向),求从s走到e经过的点数期望 思路:E[x] = sum((E[x+i]+i) * p[i])(i∈[1, m]) ,(走i步经过i个点,所以是E[x+i]+i) E[x] = sum ((E[x+i]+i) * p[i])----> E[x] - sum(p[i]*E[x+i]) = sum(i*p[i]) 代码: #include <iostream> #i

hdu 4418 高斯消元求期望

Time travel Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1480    Accepted Submission(s): 327 Problem Description Agent K is one of the greatest agents in a secret organization called Men in B

【HDU】4418 Time travel

http://acm.hdu.edu.cn/showproblem.php?pid=4418 题意:一个0-n-1的坐标轴,给出起点X.终点Y,和初始方向D(0表示从左向右.1表示从右向左,-1表示起点或终点),在走的过程中如果到达起点或终点,那么下一步往反方向走.每次可以走1-m步,每步概率为p[i],问走到终点的期望步数.(n,m,X,Y<=100) #include <cstdio> #include <algorithm> #include <cstring&g

hdu 4481 Time travel(高斯求期望)

http://acm.hdu.edu.cn/showproblem.php?pid=4418 读了一遍题后大体明白意思,但有些细节不太确定.就是当它处在i点处,它有1~m步可以走,但他走的方向不确定呢.后来想想这个方向是确定的,就是他走到i点的方向,它会继续朝着这个方向走,直到转向回头. 首先要解决的一个问题是处在i点处,它下一步该到哪个点.为了解决方向不确定的问题,将n个点转化为2*(n-1)个点.例如当n=4时由原来的0123变为012321,它对应的编号为012345,这样就不用管它哪个方

【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在这个循环节中的位置.设$

HDU 4418 高斯消元解决概率期望

题目大意: 一个人在n长的路径上走到底再往回,走i步停下来的概率为Pi , 求从起点开始到自己所希望的终点所走步数的数学期望 因为每个位置都跟后m个位置的数学期望有关 E[i] = sigma((E[i+j]+j)*P[j]) 我们需要将模型转化一下,本来路径为012345这样,因为来回走,我们多定义n-2个点就是 0123454321然后利用取模就可以不断找到下一组相关的m个点 列出多元方程组,利用高斯消元解决问题 1 #include <cstdio> 2 #include <cst

HDU OJ 5441 Travel 2015online E

题目:click here 题意: 有个很暴躁的人,想坐车旅行n个城市.连接城市共有m条路(双向).他坐在车上很不爽,每次最多忍耐x分钟.但是每站下车他又可以休息(重新计时).总共有q次询问.问途中有多少条路他可以不爆发.a到b 和 b到a 算不同的路. a 和 b 必须不相同.  分析: 并查集 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 5 using namespace st

HDU 4418 高斯消元法求概率DP

把两种状态化成2*n-2的一条线上的一种状态即可.很容易想到. 高斯列主元法,不知为什么WA.要上课了,不玩了...逃了一次课呢.. #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; double const eps=1e-8; double G[210][210];