zoukankan      html  css  js  c++  java
  • CF605E Intergalaxy Trips

    题解

    这道题目的题解也太拉了吧。

    我感觉我现在已经明白了它的真实奥义了!!!

    首先我们可以考虑逆序思考,即 (E_i) 表示第 (i) 个点到第 (n) 个点的期望天数,在不考虑自环的情况下。

    我们再令一个点确定要走的边都不走的概率是 (P_i) ,那么易得该点期望等待天数就是 (frac{1}{1-P_i})

    我们需要明白的是,如果我们已知期望值前若干小的点的期望值 (E_i) ,我们就可以利用这几个点的值来计算出剩下的点往这几个点的走的期望 (E'_j) 是多少,注意,这里的期望是仅仅走向已知点的期望值,并未考虑未知的点两两之间的影响。

    我们现在考虑未知点的两两之间对于期望的影响。由于我们已知的期望值 (E_i) 都是前若干小的,所以我们必然可以得到,未知的点的此时计算出来的期望值 (E'_j) ,如果 (j_1 ightarrow j_2) 的转移是有贡献的,必然此时的 (E'_{j_1}>E'_{j_2}) ,这个我们可以通过转移的式子来得到。

    [E_u=sum_vfrac{E_v}{1-P_v}cdot p_{u,v}prod_{E_w<E_v}(1-p_{u,w}) ]

    我们考虑相反的操作,必然会使得 (E_{j_1}) 增大,这并不优。

    然后我们就考虑一直执行这样的步骤就行了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e3+5;
    int n;bool tag[N];
    double E[N],f[N],p[N][N];
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j)
    		scanf("%lf",&p[i][j]),p[i][j]/=100;
    	}
    	tag[n]=true,E[n]=0;
    	for(int i=1;i<n;++i) E[i]=1,f[i]=1-p[i][n];
    	for(int i=1;i<n;++i){
    		int pos=-1;double Min=1e9+7;
    		for(int j=1;j<=n;++j){
    			if(tag[j]) continue;
    			if(Min>E[j]/(1-f[j]))
    			Min=E[j]/(1-f[j]),pos=j;
    		}
    		tag[pos]=true;
    		// printf("%d %.7lf
    ",pos,E[pos]/(1-f[pos]));
    		for(int j=1;j<=n;++j){
    			if(tag[j]) continue;
    			E[j]+=E[pos]/(1-f[pos])*p[j][pos]*f[j],f[j]*=1-p[j][pos];
    		}
    	}
    	return printf("%.7lf
    ",E[1]/(1-f[1])),0;
    }
    
  • 相关阅读:
    VC++6.0 自定义按钮,无标题对话框的拖动方法
    完整的使用线程池的多线程C/S Socket类
    树形控件Tree Control
    关闭数据执行保护
    VC++开发垃圾文件清理软件(下)
    用完成端口开发大响应规模的Winsock应用程序
    去掉右键多余显卡菜单
    自动登陆系统
    查询数据库中所有表名和表中所有字段名
    单行编辑框文本垂直居中(包含计算字体高度)
  • 原文地址:https://www.cnblogs.com/Point-King/p/15168049.html
Copyright © 2011-2022 走看看