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];

int n,m,s,e,d; double sum;
double pk[110];
double ans[210];

bool find(int i){
	int k=i;
	for(int j=i+1;j<n;j++){
		if(fabs(G[j][i])>fabs(G[k][i]))
		k=j;
	}
	if(fabs(G[k][i])<eps) return false;
	for(int p=i;p<=n;p++)
	swap(G[i][p],G[k][p]);
	return true;
}

bool Guass(){
	for(int i=0;i<n;i++){
		if(find(i)){
			for(int j=i+1;j<n;j++){
				double k=G[j][i]/G[i][i];
				for(int p=i;p<=n;p++)
				G[j][p]=G[j][p]-k*G[i][p];
			}
		}
		else return false;
	}

	ans[n-1]=G[n-1][n]/G[n-1][n-1];
	for(int i=n-2;i>=0;i--){
		double sum=0;
		for(int j=n-1;j>i;j--){
			sum+=(G[i][j]*ans[j]);
		}
		ans[i]=(G[i][n]-sum)/G[i][i];
	}
	return true;
}

int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d%d%d%d",&n,&m,&e,&s,&d);
		sum=0;
		n=2*n-2;
		for(int i=1;i<=m;i++){
			scanf("%lf",&pk[i]);
			pk[i]/=100;
			sum+=(i*pk[i]);
		}
		if (s == e){
            puts ("0.00");
            continue;
        }
		if(d==0) s=s;
		else if(d==1) s=(n-s)%n;
		memset(G,0,sizeof(G));
		for(int i=0;i<n;i++){
			G[i][i]=-1;
			if(i==e||i==n-e) continue;

			for(int j=1;j<=m;j++){
				G[i][(j+i)%n]=pk[j];
			}
			G[i][n]=-sum;
		}
		if(!Guass()){
			puts("Impossible !");
		}
		else{
			if(ans[s]<eps) puts("Impossible !");
			else
			printf("%.2f\n",ans[s]);
		}
	}
	return 0;
}

  这个是别人的

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <math.h>
using namespace std;
#define M 205
#define eps 1e-8
int equ, var;
double a[M][M], x[M];

int Gauss ()
{
	int i, j, k, col, max_r;
	for (k = 0, col = 0; 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 (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 = 0; i < equ; i++) if (i != k)
		{
			x[i] -= x[k] * a[i][k];
			for (j = col+1; j < var; j++) a[i][j] -= a[k][j] * a[i][col];
			a[i][col] = 0;
		}
	}
	return 1;
}

//has[x]表示人在x点时的变量号,因为我们只用可达状态建立方程,所以需要编号
int has[M], vis[M], k, e, n, m;
double p[M], sum;

int bfs (int u)
{
	memset (has, -1, sizeof(has));
	memset (a, 0, sizeof(a));			//忘记初始化WA勒,以后得注意
	memset (vis, 0, sizeof(vis));
	int v, i, flg = 0;
	queue<int> q;
	q.push (u);
	k = 0;
	has[u] = k++;
	while (!q.empty ())
	{
		u = q.front ();
		q.pop ();
		if (vis[u]) continue;
		vis[u] = 1;
		if (u == e || u == n-e)		//终点有两个,你懂的~
		{
			a[has[u]][has[u]] = 1;
			x[has[u]] = 0;
			flg = 1;
			continue;
		}
		//E[x] = sum ((E[x+i]+i) * p[i])
		// ----> E[x] - sum(p[i]*E[x+i]) = sum(i*p[i])
		a[has[u]][has[u]] = 1;
		x[has[u]] = sum;
		for (i = 1; i <= m; i++)
		{
			//非常重要!概率为0,该状态可能无法到达,如果还去访问并建立方程会导致无解
			if (fabs (p[i]) < eps) continue;
			v = (u + i) % n;
			if (has[v] == -1) has[v] = k++;
			a[has[u]][has[v]] -= p[i];
			q.push (v);
		}
	}
	return flg;
}

int main()
{
	int t, s, d, i;
	scanf ("%d", &t);
	while (t--)
	{
		scanf ("%d%d%d%d%d", &n, &m, &e, &s, &d);
		n = 2*(n-1);
		sum = 0;
		for (i = 1; i <= m; i++)
		{
			scanf ("%lf", p+i);
			p[i] = p[i] / 100;
			sum += p[i] * i;
		}
		if (s == e)
		{
			puts ("0.00");
			continue;
		}
		//一开始向左,起点要变
		if (d > 0) s = (n - s) % n;
		if (!bfs (s))
		{
			puts ("Impossible !");
			continue;
		}
		equ = var = k;

		Gauss ();
		printf ("%.2f\n", x[has[s]]);
	}
    return 0;
}

  

时间: 2024-10-29 10:28:27

HDU 4418 高斯消元法求概率DP的相关文章

HDU 4050 wolf5x (概率DP 求期望)

题意:有N个格子,1~N,起点在0,每个格子有一个状态(0,1,2,3),每次可以跨[a,b]步, 问走完N个格子需要步数的期望,每次尽量走小的步数,即尽量走a步,不能则走a+1,-- 状态0意味着你不能踏进对应的网格. 状态1意味着你可以??步入网格用你的左腿. 状态2意味着你可以??步入网格用你的右腿. 状态3意味着你可以进入网格用任何你的腿,而接下来的步骤中,您可以使用任何的腿;即你不需要遵循上述规则. 思路:借鉴了各路大神的思想理解了下. dp[i][j] :表示走到第 i 个格子在 j

[ACM] HDU 4576 Robot (概率DP,滚动数组)

Robot Problem Description Michael has a telecontrol robot. One day he put the robot on a loop with n cells. The cells are numbered from 1 to n clockwise. At first the robot is in cell 1. Then Michael uses a remote control to send m commands to the ro

HDU 4652 Dice (概率DP)

Dice Problem Description You have a dice with m faces, each face contains a distinct number. We assume when we tossing the dice, each face will occur randomly and uniformly. Now you have T query to answer, each query has one of the following form: 0

HDU 3366 Passage (概率DP)

Passage Problem Description Bill is a millionaire. But unfortunately he was trapped in a castle. There are only n passages to go out. For any passage i (1<=i<=n), Pi (0<=Pi<=1) denotes the probability that Bill will escape from this castle saf

[ACM] hdu 4405 Aeroplane chess (概率DP)

Aeroplane chess 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 probability to face up and the number

[ACM] hdu 3853 LOOPS (概率DP,递推)

LOOPS Problem Description Akemi Homura is a Mahou Shoujo (Puella Magi/Magical Girl). Homura wants to help her friend Madoka save the world. But because of the plot of the Boss Incubator, she is trapped in a labyrinth called LOOPS. The planform of the

HDU 4336 Card Collector(概率DP)

 题意:有n种卡片,吃零食的时候会吃到一些卡片,告诉你在一袋零食中吃到每种卡片的概率,求搜集齐每种卡片所需要买零食的袋数的期望. 思路:先状态压缩,然后概率DP 用d[i]表示由状态i到目标需要再买多少包,则状态转移方程为d[i] = p'*(d[i]+1) + sigma(d[ i | (1 << j) * p[i] ),然后相同项移到左边,最后就可以得到答案. #include<cstdio> #include<cstring> #include<cmat

HDU - 5001 Walk(概率dp+记忆化搜索)

Walk I used to think I could be anything, but now I know that I couldn't do anything. So I started traveling. The nation looks like a connected bidirectional graph, and I am randomly walking on it. It means when I am at node i, I will travel to an ad

HDU 3853 LOOPS(概率dp求期望啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3853 Problem Description Akemi Homura is a Mahou Shoujo (Puella Magi/Magical Girl). Homura wants to help her friend Madoka save the world. But because of the plot of the Boss Incubator, she is trapped in