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,这样就不用管它哪个方向,统一处理了,当向前走k步时即(i+k)%n。

然后设出dp[i]表示在i点处时到达终点的期望步数,那么可列出转移方程dp[i] = ∑( pk * (dp[ (x+k)%n ] +k) )。但是有些点是永远无法到达的,因此先bfs出所有到达的点,然后列出方程组解方程。

有许多注意的点,判断p[i]是否为0等。

#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
//#define LL __int64
#define LL long long
#define eps 1e-9
#define PI acos(-1.0)
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 210;

double p[maxn];
double a[maxn][maxn];//增广矩阵
double X[maxn];//解集
int num[maxn];//给每个能给到达的point离散化
int n,m,x,y,d;
int equ,var,cnt;

bool Gauss()
{
    int row,col,max_r,i,j;
    row = 0;
    col = 0;
    while(row < equ && col < var)
    {
        max_r = row;
        for(i = row+1; i < equ; i++)
        {
            if(fabs(a[i][col]) > fabs(a[max_r][col]))
                max_r = i;
        }
        if(max_r != row)
        {
            for(j = col; j <= var; j++)
                swap(a[row][j], a[max_r][j]);
        }
        if(fabs(a[row][col]) < eps)
        {
            col++;
            continue;
        }
        for(i = row+1; i < equ; i++)
        {
            if(fabs(a[i][col]) < eps) continue;
            double t = a[i][col]/a[row][col];
            a[i][col] = 0.0;
            for(j = col+1; j <= var; j++)
                a[i][j] -= a[row][j]*t;
        }
        row++;
        col++;
    }

    for(i = row; i < equ; i++)
        if(fabs(a[i][var]) > eps)
            return false; //无解
    for(i = equ-1; i >= 0; i--)
    {
        if(fabs(a[i][i]) < eps) continue;
        double t = a[i][var];
        for(j = i+1; j < var; j++)
            t -= a[i][j]*X[j];
        X[i] = t/a[i][i];
    }
    return true;
}

void bfs(int s) //bfs找出所有能够到达的点并离散化
{
    queue <int> que;
    que.push(s);
    num[s] = cnt++;
    while(!que.empty())
    {
        int u = que.front();
        que.pop();
        for(int i = 1; i <= m; i++)
        {
            if(fabs(p[i]) < eps)
                continue;
            int v = (u+i)%n;
            if(num[v] == -1)
            {
                num[v] = cnt++;
                que.push(v);
            }
        }
    }
}

int main()
{
	int test;
	scanf("%d",&test);
	for(int item = 1; item <= test; item++)
	{
		scanf("%d %d %d %d %d",&n,&m,&y,&x,&d);
		for(int i = 1; i <= m; i++)
		{
			scanf("%lf",&p[i]);
			p[i] /= 100;
		}
		if(x == y)
		{
			printf("0.00\n");
			continue;
		}
		n = 2*(n-1);
		if(d == 1)
            x = n-x;
		memset(num,-1,sizeof(num));
		cnt = 0;
		bfs(x);
		if(num[y] == -1 && num[n-y] == -1) //注意这里是 &&,只有当两个方向都走不到才算走不到
		{
		    printf("Impossible !\n");
		    continue;
		}

		memset(a,0,sizeof(a));
		memset(X,0,sizeof(X));
		equ = var = cnt;

		for(int i = 0; i < n; i++)
		{
		    if(num[i] != -1)
		    {
		        if(i == y || i == n-y) //注意特判终点
                {
                    a[num[i]][num[i]] = 1;
                    a[num[i]][cnt] = 0;
                    continue;
                }
		        a[num[i]][num[i]] = 1;
		        for(int j = 1; j <= m; j++)
		        {
		            int t = (i+j)%n;
		            if(num[t] != -1)
                        a[num[i]][num[t]] -= p[j];
                    a[num[i]][cnt] += j*p[j];
		        }
		    }
		}
		if(Gauss())
            printf("%.2lf\n",X[num[x]]);
        else printf("Impossible !\n");
	}
	return 0;
}
时间: 2024-10-12 03:21:18

hdu 4481 Time travel(高斯求期望)的相关文章

HDU 5245 Joyful (概率题 求期望)

Joyful Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 478    Accepted Submission(s): 209 Problem Description Sakura has a very magical tool to paint walls. One day, kAc asked Sakura to paint a

HDU 5345 Joyful(概率题求期望)

D - Joyful Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description Sakura has a very magical tool to paint walls. One day, kAc asked Sakura to paint a wall that looks like an $M \times N$ matrix. The wal

ZJUT 地下迷宫 (高斯求期望)

http://cpp.zjut.edu.cn/ShowProblem.aspx?ShowID=1423 设dp[i]表示在i点时到达终点要走的期望步数,那么dp[i] = ∑1/m*dp[j] + 1,j是与i相连的点,m是与i相邻的点数,建立方程组求解.重要的一点是先判断DK到达不了的点,需要bfs预处理一下进行离散化,再建立方程组. #include <stdio.h> #include <iostream> #include <map> #include <

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 2262 高斯消元求期望

Where is the canteen Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1070    Accepted Submission(s): 298 Problem Description After a long drastic struggle with himself, LL decide to go for some

hdu 3992 AC自动机上的高斯消元求期望

Crazy Typewriter Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 391    Accepted Submission(s): 109 Problem Description There was a crazy typewriter before. When the writer is not very sober, it

hdu 4405 Aeroplane chess(概率DP 求期望__附求期望讲解方法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4405 Problem Description Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he throws a dice(a dice have six faces with equal p

HDU4870_Rating_双号从零单排_高斯消元求期望

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870 原题: Rating Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 654    Accepted Submission(s): 415 Special Judge Problem Description A little gir

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>