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

    题目

    题目链接:https://codeforces.com/problemset/problem/235/C

    • (n) 个点的有向完全图。
    • (i o j) 的边每天出现的概率均为 (p_{i,j}),若 (i = j),有 (p_{i,j} = 1)
    • 每天选择一条存在的出边走过去。
    • 求最优策略下从 (1)(n) 的期望天数。
    • (n le 10^3)

    思路

    (f_i) 表示从点 (i) 到点 (n) 的期望步数。
    显然当我们最终把 (f) 按从小到大排序之后,一定是排在后面的转移到排在前面的。
    所以我们需要确定一个顺序保证转移只会从最终 (f) 较小的转移到 (f) 较大的。
    不难发现在某一个状态下,肯定选择没有选择过且 (f) 最小的进行转移就可以满足上述条件。所以我们用类似 dij 的转移方式。
    那么有

    [f_i=sum^{}_{f_j<f_i}f_j imes p_{i,j} imes sum^{}_{f_k<f_j}(1-p_{i-k}) ]

    因为如果我们考虑走到 (j),当且仅当比它期望步数更小的我们都没法走,且我们能走向 (j)
    (g_i) 为截止当前转移最后一个 (sum) 内的值,就可以 (O(1)) 转移了。
    时间复杂度 (O(n^2))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=1010;
    int n;
    double f[N],g[N],p[N][N];
    bool vis[N];
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    	{
    		f[i]=g[i]=1;
    		for (int j=1;j<=n;j++)
    		{
    			scanf("%lf",&p[i][j]);
    			p[i][j]/=100.0;
    		}
    	}
    	f[n]=g[n]=0;
    	for (int i=1;i<=n;i++)
    	{
    		int x=0;
    		for (int j=1;j<=n;j++)
    			if (!vis[j] && g[j]<1 && (!x || f[j]/(1-g[j])<f[x]/(1-g[x]))) x=j;
    		vis[x]=1; f[x]/=(1-g[x]);
    		for (int j=1;j<=n;j++)
    			if (!vis[j])
    			{
    				f[j]+=f[x]*p[j][x]*g[j];
    				g[j]*=(1-p[j][x]);
    			}
    	}
    	printf("%.10lf",f[1]);
    	return 0;
    }
    
  • 相关阅读:
    kakfa 入门
    Spring Boot maven构建——阿里云Maven仓库地址
    MongoDB入门一
    MongoDB入门
    mybatis 一对一、一对多、多对一、多对多
    springboot集成druid数据源并且监控
    java 过滤表情符号
    Mybatis框架
    表单(一)
    HTML标签(二)
  • 原文地址:https://www.cnblogs.com/stoorz/p/14270197.html
Copyright © 2011-2022 走看看