●Joyoi Dotp 驱逐猪猡

题链:

http://www.joyoi.cn/problem/tyvj-2610
题解:

期望dp,高斯消元

对于每一种到达i点的方案,都存在一个概率p,
令dp[i]表示到达i点的期望次数,那么容易由期望的定义得出:
dp[i]=p1*1+p2*1+p3*1+......(每个概率对应的权值都为1)

如果我们知道了每个点的期望的到达次数,那么在该点期望的爆炸次数=期望的到达次数*P/Q
就可以求出一个SUM=dp[1]+dp[2]+...+dp[N]
然后每个点的爆炸的概率就是(dp[i]*P/Q)/(SUM*P/Q)=dp[i]/SUM
(因为期望的权值都为1,所以概率的比例就等于期望的比例)

这种解法,更容易理解。
http://blog.csdn.net/neither_nor/article/details/52292240
如果在每个点爆炸的概率不同的话,那应该只能像这个拆点的方法做了。

没有SPJ,输出9位小数才能过2333

代码:

#include<bits/stdc++.h>
#define MAXN 305
using namespace std;
const double eps=1e-8;
struct Edge{
	int ent;
	int to[MAXN*MAXN*2],nxt[MAXN*MAXN*2],head[MAXN];
	Edge():ent(2){}
	void Adde(int u,int v){
		to[ent]=v; nxt[ent]=head[u]; head[u]=ent++;
		to[ent]=u; nxt[ent]=head[v]; head[v]=ent++;
	}
}E;
double a[MAXN][MAXN],dp[MAXN],K,SUM;
double *A[MAXN];
int cnt[MAXN];
int N,M,P,Q;
int dcmp(double x){
	if(fabs(x)<eps) return 0;
	return x>0?1:-1;
}
void buildequation(){
	for(int i=1;i<=N;i++){
		a[i][i]=-1;
		if(i==1) a[i][N+1]=-1;
		for(int e=E.head[i];e;e=E.nxt[e]){
			int j=E.to[e];
			a[i][j]=K*1.0/cnt[j];
		}
	}
	for(int i=1;i<=N;i++) A[i]=a[i];
}
void Gausselimination(int pos,int i){
	if(pos==N+1||i==N+1) return;
	for(int j=pos;j<=N;j++) if(dcmp(A[pos][i])!=0){
		swap(A[j],A[pos]); break;
	}
	if(dcmp(A[pos][i])!=0)
		for(int j=pos+1;j<=N;j++){
			double k=A[j][i]/A[pos][i];
			for(int l=i;l<=N+1;l++)
				A[j][l]-=k*A[pos][l];
		}
	Gausselimination(pos+(dcmp(A[pos][i])!=0),i+1);
	if(dcmp(A[pos][i])!=0){
		for(int l=i+1;l<=N;l++)
			dp[i]+=A[pos][l]*dp[l];
		dp[i]=A[pos][N+1]-dp[i];
		dp[i]=dp[i]/A[pos][i];
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin>>N>>M>>P>>Q;
	K=(1-1.0*P/Q);
	for(int i=1,u,v;i<=M;i++)
		cin>>u>>v,E.Adde(u,v),
		cnt[u]++,cnt[v]++;
	buildequation();
	Gausselimination(1,1);
	for(int i=1;i<=N;i++) SUM+=dp[i];
	cout<<fixed<<setprecision(9);
	for(int i=1;i<=N;i++) cout<<fabs(dp[i]/SUM)<<endl;
	return 0;
}

  

原文地址:https://www.cnblogs.com/zj75211/p/8543041.html

时间: 2024-10-03 14:45:51

●Joyoi Dotp 驱逐猪猡的相关文章

BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡

1778: [Usaco2010 Hol]Dotp 驱逐猪猡 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 563  Solved: 216[Submit][Status][Discuss] Description 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两个不同端点A_j和B_j (1 <= A_j<

【bzoj1778】[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元

题目描述 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两个不同端点A_j和B_j (1 <= A_j<= N; 1 <= B_j <= N)表示的双向道路连接.保证城市1至少连接一个其它的城市.一开始臭气弹会被放在城市1.每个小时(包括第一个小时),它有P/Q (1 <= P <=1,000,000; 1 <= Q <

BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元

题意: 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两个不同端点A_j和B_j (1 <= A_j<= N; 1 <= B_j <= N)表示的双向道路连接.保证城市1至少连接一个其它的城市.一开始臭气弹会被放在城市1.每个小时(包括第一个小时),它有P/Q (1 <= P <=1,000,000; 1 <= Q <

BZOJ1778 [Usaco2010 Hol]Dotp 驱逐猪猡

首先我们列出转移矩阵$M$,$M_{i, j} = \frac {1 - \frac{p} {q}} {deg[i]}$(i,j之间有边)or $M_{i, j} = 0$(i,j之间没边) 则这个矩阵$M_{i, j}$表示的是站在某个点$i$,下一次走到$j$且没有爆炸的概率 我们再看$M^n_{i, j}$,表示的站在某个点$i$,走$n$步以后到达$j$且没有爆炸的概率 故$M^n$的第一列代表了$1$号点到其他所有点的概率,设为列向量$A_n$,则$A_n = M^n * B$,其中$

BZOJ 1778 Usaco2010 Hol Dotp 驱逐猪猡 期望DP+高斯消元

题目大意:给定一个无向图,炸弹从1号节点出发,每个时刻有P/Q的概率爆炸,如果某个时刻没有爆炸,就会等概率沿着随机一条出边走到下一个城市,求最终每个城市的爆炸概率 #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 330 using namespace std; int n,m,p,q;

【BZOJ】1778: [Usaco2010 Hol]Dotp 驱逐猪猡

[题意]给定无向图,炸弹开始在1,在每个点爆炸概率p/q,不爆炸则等概率往邻点走,求在每个点爆炸的概率. [算法]数学概率期望+高斯消元 [题解]令f[i]表示炸弹到达i点的概率(之前不爆炸). f[i]=∑f[j]*(1-Q)/d[j] 特别的,f[1]=∑f[j]*(1-Q)/d[j]+1(一开始就到达). 只要一个点到就是到达,故使用概率加法. 使用高斯消元求解方程组,最后ansi=f[i]*Q. 另一种思路,由于炸弹最终爆炸概率为1,所以sum=∑f[i],ansi=f[i]/sum 此

BZOJ_1778_[Usaco2010_Hol]_Dotp_驱逐猪猡_(期望动态规划+高斯消元+矩阵)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1778 炸弹从1出发,有\(\frac{P}{Q}\)的概率爆炸,如果不爆炸,等概率移动到连通的点.求在每个点爆炸的概率. 分析 我们构造一个\(n\)行\(n\)列的矩阵\(f\),其中\(f[i][j]\)表示从\(i\)移动到\(j\)的概率. 那么\(f^2\)中\(f^2[i][j]\)是\(f[i][k]\times{f[k][j]}\)得来的,也就是\(i\to{k}\to{j}

BZOJ 3270 博物馆 期望DP+高斯消元

题目大意:给定一张无向连通图,两个人初始各在某个点上,每个时刻每个人会不动或任选出边走,求两人最终期望在哪里相遇 把点数平方,原图上的两个点(x,y)变成新图上的一个点 然后令A为这个图的邻接矩阵(若两人在同一点上则没有出边,否则按概率转移),S为初始行向量(S[(a,b)]=1),ans为答案行向量 那么有ans=S+SA+SA^2+SA^3+... =S(I-A^+∞)/(I-A) =S/(I-A) 于是有ans*(I-A)=S 于是对I-A的转置求高斯消元即可. 和驱逐猪猡那题的思路很像.

【BZOJ】3143: [Hnoi2013]游走 期望+高斯消元

[题意]给定n个点m条边的无向连通图,每条路径的代价是其编号大小,每个点等概率往周围走,要求给所有边编号,使得从1到n的期望总分最小(求该总分).n<=500. [算法]期望+高斯消元 [题解]显然,应使经过次数越多的边编号越小,问题转化为求每条边的期望经过次数. 边数太多,容易知道f(u,v)=f(u)/out(u)+f(v)/out(v),所以转化为求每个点的期望经过次数,这就是驱逐猪猡了. 设f[x]表示点x的期望经过次数,根据全期望公式(讨论"经过"的问题不能依赖于下一步