标签:CF605E 期望 int 期望值 pos Intergalaxy 考虑 我们 Trips
题解
这道题目的题解也太拉了吧。
我感觉我现在已经明白了它的真实奥义了!!!
首先我们可以考虑逆序思考,即 \(E_i\) 表示第 \(i\) 个点到第 \(n\) 个点的期望天数,在不考虑自环的情况下。
我们再令一个点确定要走的边都不走的概率是 \(P_i\) ,那么易得该点期望等待天数就是 \(\frac{1}{1-P_i}\) 。
我们需要明白的是,如果我们已知期望值前若干小的点的期望值 \(E_i\) ,我们就可以利用这几个点的值来计算出剩下的点往这几个点的走的期望 \(E'_j\) 是多少,注意,这里的期望是仅仅走向已知点的期望值,并未考虑未知的点两两之间的影响。
我们现在考虑未知点的两两之间对于期望的影响。由于我们已知的期望值 \(E_i\) 都是前若干小的,所以我们必然可以得到,未知的点的此时计算出来的期望值 \(E'_j\) ,如果 \(j_1\rightarrow j_2\) 的转移是有贡献的,必然此时的 \(E'_{j_1}>E'_{j_2}\) ,这个我们可以通过转移的式子来得到。
\[E_u=\sum_v\frac{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\n",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\n",E[1]/(1-f[1])),0;
}
标签:CF605E,期望,int,期望值,pos,Intergalaxy,考虑,我们,Trips 来源: https://www.cnblogs.com/Point-King/p/15168049.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。