hdu-4418-Time travel-高斯+概率dp

把N个点先转化为2*N-2个点。

比如说把012345转化成0123454321。

这样,就可以找出任意两两个点之间的关系。

然后根据关系可以得出来一个一元多项式的矩阵。

然后就用高斯消元求出矩阵即可。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
using namespace std;
#define eps 1e-6
#define zero(x) ((fabs(x)<eps?0:x))
#define maxn 220
double a[maxn][maxn];
int g[maxn],cnt;
int n,m,st,ed;
double p[maxn];
int guss(int n)
{
    int r;
    for(int i=0;i<n;i++)
    {
        r=i;
        for(int j=i+1;j<n;j++)
        {
            if(fabs(a[j][i])>fabs(a[r][i]))r=j;
        }
        if(!zero(a[r][i]))return 0;
        if(r!=i){
                for(int j=0;j<=n;j++)
                    swap(a[i][j],a[r][j]);
        }
        for(int j=i+1;j<=n;j++)a[i][j]/=a[i][i];
        a[i][i]=1.0;
        for(int j=0;j<n;j++)
        {
            if(j==i)continue;
            for(int k=i+1;k<=n;k++)
            {
                a[j][k]-=a[i][k]*a[j][i];
            }
            a[j][i]=0;
        }
    }
    return 1;
}
void bfs()
{
    queue<int>que;
    while(!que.empty())que.pop();
    que.push(st);
    memset(g,-1,sizeof(g));
    cnt=0;
    g[st]=cnt++;
    while(!que.empty())
    {
        int x=que.front();
        que.pop();
        for(int i=1;i<=m;i++)
        {
            if(!zero(p[i]))continue;
            int y=(i+x)%n;
            if(g[y]==-1)
            {
                g[y]=cnt++;
                que.push(y);
            }
        }
    }
}
int main()
{
    int T,d;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d%d",&n,&m,&ed,&st,&d);
        for(int i=1;i<=m;i++)
        {
            scanf("%lf",&p[i]);
            p[i]=1.0*p[i]/100.0;
        }
        if(ed==st)
        {
            puts("0.00");
            continue;
        }
        n=2*n-2;
        if(d==1)st=n-st;
        bfs();
        if(g[ed]==-1&&g[n-ed]==-1){
                puts("Impossible !");
                continue;
        }
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            if(g[i]==-1)continue;
            if(i==ed||i==n-ed)
            {
                a[g[i]][g[i]]=1;
                a[g[i]][cnt]=0;
                continue;
            }
            a[g[i]][g[i]]=1.0;
            for(int j=1;j<=m;j++)
            {
                int y=(i+j)%n;
                if(g[y]==-1)continue;
                a[g[i]][g[y]]-=p[j];
                a[g[i]][cnt]+=1.0*j*p[j];
            }
        }
        if(!guss(cnt))puts("Impossible !");
        else printf("%.2lf\n",a[g[st]][cnt]);
    }
    return 0;
}

hdu-4418-Time travel-高斯+概率dp

时间: 2024-08-26 02:44:17

hdu-4418-Time travel-高斯+概率dp的相关文章

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

HDU 4865 Peter&#39;s Hobby --概率DP

题意:第i天的天气会一定概率地影响第i+1天的天气,也会一定概率地影响这一天的湿度.概率在表中给出.给出n天的湿度,推测概率最大的这n天的天气. 分析:这是引自机器学习中隐马尔科夫模型的入门模型,其实在这里直接DP就可以了 定义:dp[i][j]为第i天天气为j(0,1,2分别表示三个天气)的概率,path[i][j]记录路径,path[i][j] = k 意思是前一天天气为k时,这一天有最大的概率是天气j. 做一个三重循环,对于每天,枚举今天的天气,再在里面枚举昨天的天气,则有: dp[i][

HDU 4405 Aeroplane chess (概率DP求期望)

题意:有一个n个点的飞行棋,问从0点掷骰子(1~6)走到n点需要步数的期望 其中有m个跳跃a,b表示走到a点可以直接跳到b点. dp[ i ]表示从i点走到n点的期望,在正常情况下i点可以到走到i+1,i+2,i+3,i+4,i+5,i+6 点且每个点的概率都为1/6 所以dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])/6  + 1(步数加一). 而对于有跳跃的点直接为dp[a]=dp[b]; #include<stdio.h>

hdu 3076 ssworld VS DDD (概率dp)

///题意: /// A,B掷骰子,对于每一次点数大者胜,平为和,A先胜了m次A赢,B先胜了n次B赢. ///p1表示a赢,p2表示b赢,p=1-p1-p2表示平局 ///a赢得概率 比一次p1 两次p0*p1 三次 p0^2*p1,即A赢的概率为p1+p*p1+p^2*p1+...p^n*p1,n->无穷 ///即a_win=p1/(1-p);b_win=p2/(1-p); ///dp[i][j]表示a赢了j次,b赢了i次的概率 ///dp[i][j]=dp[i-1][j]*b_win+dp[

HDU 4050 wolf5x(动态规划-概率DP)

wolf5x Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 402    Accepted Submission(s): 248 Special Judge Problem Description There are n grids in a row. The coordinates of grids are numbered fro

HDU 4336——Card Collector——————【概率dp】

Card Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3407    Accepted Submission(s): 1665Special Judge Problem Description In your childhood, do you crazy for collecting the beautiful

hdu 4405 Aeroplane chess (概率DP)

Aeroplane chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1503    Accepted Submission(s): 1025 Problem Description Hzz loves aeroplane chess very much. The chess map contains N+1 grids la

【期望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 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,这样就不用管它哪个方

HDU 5001 Walk (暴力、概率dp)

Walk Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 266    Accepted Submission(s): 183 Special Judge Problem Description I used to think I could be anything, but now I know that I couldn't d