首页 > 其他 > 详细

CF605E

时间:2020-07-08 14:43:23      阅读:51      评论:0      收藏:0      [点我收藏+]

https://www.cnblogs.com/cjyyb/p/9707853.html
https://www.cnblogs.com/daklqw/p/12009106.html
每次应该找出边中期望天数\(E(x)\)尽量小的走过去
假设找出了一个排列\(P\)使得\(E(P_i)\)\(i\)单调不降

\[E(P_i)=\dfrac{\sum_{j<i} E(P_j)\times p_{P_i,P_j}\prod_{k<j}(1?p_{P_i,P_k})}{1-\prod_{j<i}p_{P_i,P_j}} \]

除掉\(1-\prod p\)是因为有这个概率所有边都走不了所以只能停留在原地
大概是类似dij一样每次取出\(E(x)\)最小的\(x\)更新别人 但不是很会证明正确性 具体还是看daklqw博客吧...

#include<bits/stdc++.h>
using namespace std;
#define fp(i,l,r) for(register int (i)=(l);i<=(r);++(i))
#define fd(i,l,r) for(register int (i)=(l);i>=(r);--(i))
#define fe(i,u) for(register int (i)=front[(u)];(i);(i)=e[(i)].next)
#define mem(a) memset((a),0,sizeof (a))
#define O(x) cerr<<#x<<‘:‘<<x<<endl
#define prev pku
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();}
	while(isdigit(ch))x=x*10+ch-‘0‘,ch=getchar();
	return x*f;
}
void wr(int x){
	if(x<0)putchar(‘-‘),x=-x;
	if(x>=10)wr(x/10);
	putchar(‘0‘+x%10);
}
const int MAXN=1e3+10;
double P[MAXN][MAXN];
double dis[MAXN],prod[MAXN],tmp[MAXN];bool vis[MAXN];
int n;
main(){
	n=read();
	fp(i,1,n)fp(j,1,n)P[i][j]=1.0*read()/100.0;
	fp(i,0,n-1)dis[i]=1e100,tmp[i]=prod[i]=1;
	fp(i,1,n){
		int u=0;
		fp(j,1,n)if(!vis[j]&&dis[u]>dis[j])u=j;
		if(u==1){printf("%.10lf\n",dis[1]);return 0;}
		vis[u]=1;
		fp(v,1,n)if(!vis[v]){
			tmp[v]+=dis[u]*prod[v]*P[v][u];
			prod[v]*=1-P[v][u];
			dis[v]=tmp[v]/(1-prod[v]);
		}
	}
	return 1;
}

CF605E

原文:https://www.cnblogs.com/misaka10047/p/13266500.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!