zoukankan      html  css  js  c++  java
  • ●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;
    }
    

      

  • 相关阅读:
    052、Java中使用do…while循环实现1~100的累加
    051、Java中使用while循环实现1~100的累加
    050、Java中使用switch判断,使用字符串判断
    一个DOM元素绑定多个事件时,先执行冒泡还是捕获
    cookies,sessionStorage和localStorage的区别
    雅虎网页性能优化的35条黄金守则
    多域名指向同一个网站的好处
    减少页面加载时间的方法
    网站文件和资源的优化
    语义化的html
  • 原文地址:https://www.cnblogs.com/zj75211/p/8543041.html
Copyright © 2011-2022 走看看