• 【CF605E】Intergalaxy Trips(期望)


    点此看题面

    • 给定一张(n)个点的有向完全图,其中(x ightarrow y)的边每天有(a_{x,y})的概率出现(保证(forall x,a_{x,x}=1))。
    • 每天需要从当前点选择一条存在的出边,走到对应的点。
    • 求采取最优策略时,从(1)号点走到(n)号点的期望天数。
    • (nle10^3)

    期望真是一个玄学的东西,感觉总是不知道啥可以啥不可以。。。

    期望

    这道题中,我们设(E(x))表示采取最优策略时,从(x)走到(n)的期望步数

    一个显然的结论,若(E(x)<E(y)),则我们不会选择从(x)走到(y)。(因为这样肯定会让答案变得更大)

    如果要利用这个性质,从(1)号点出发正着做明显不太好求出(E(x))(答案就是(E(1))啊,若能直接求出还有什么好做的。。。),因此我们要从(n)号点出发倒着做。

    具体操作流程类似于(Dijkstra),每次选出(E(x))最小的点去更新其他点的。不过由于这是一张完全图,堆优化没有意义,直接暴力做即可。

    但还有一个问题没解决,如何维护、计算(E(x))

    (E(x))的计算

    假设对于一个点(x),已知有(k)个点(y_1,y_2,...,y_k)满足(E(y_1)le E(y_2)le...le E(y_k)le E(x))

    贪心地去考虑,必然是尽可能走到(y_1),次优是走到(y_2),以此类推。

    于是我们就可以用一个式子来表示(s_x)(可以理解为离开(x)(n)的期望天数,但有一点区别,后面会提到):

    [s_x=sum_{i=1}^k(E(y_i)+1) imes a_{x,y_i} imesprod_{j=1}^{i-1}(1-a_{x,y_j}) ]

    因为我们具体操作时肯定是每次找到新的(y_k)去更新每一个(s_x)的,所以我们只要维护好(p_x=prod_{i=1}^k(1-a_{x,y_k}))(p_x)的实际意义是不会离开(x)的概率),则一次更新就变成了:

    [s_x exttt{+=}(E(y)+1) imes a_{x,y} imes p_x\p_x exttt{*=}1-a_{x,y} ]

    然后考虑(E(x))的计算,我们只需分是否离开两种转移:(注意(s_x)本身就包含了(1-p_x),无需再乘上这个系数)

    [E(x)=p_x(E(x)+1)+s_x ]

    式子两边都有(E(x)),经典的移项转化,得到:

    [E(x)=frac{s_x+p_x}{1-p_x} ]

    知道了(E(x))的计算,这道题也就做完了。

    代码:(O(n^2))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 1000
    using namespace std;
    int n,vis[N+5];double s[N+5],p[N+5],a[N+5][N+5];
    int main()
    {
    	#define E(x) ((s[x]+p[x])/(1-p[x]))//计算x到n的期望天数
    	#define F5(x) vis[x]=1;for(RI i=1;i<=n;++i)
    		!vis[i]&&(s[i]+=(E(x)+1)*p[i]*a[i][x],p[i]*=1-a[i][x]);//用当前最优点x更新剩余点
    	RI i,j,t;for(scanf("%d",&n),i=1;i<=n;++i)
    		for(j=1;j<=n;++j) scanf("%lf",a[i]+j),a[i][j]/=100;
    	for(i=1;i^n;++i) p[i]=1;F5(n);for(i=1;i<=n&&!vis[1];++i)
    		{for(t=0,j=1;j<=n;++j) !vis[j]&&(!t||E(t)>E(j))&&(t=j);F5(t);}//每次选取最优点转移
    	return printf("%.10lf
    ",E(1)),0;
    }
    
  • 相关阅读:
    How to function call using 'this' inside forEach loop
    jquery.validate.unobtrusive not working with dynamic injected elements
    Difference between jQuery.extend and jQuery.fn.extend?
    Methods, Computed, and Watchers in Vue.js
    Caution using watchers for objects in Vue
    How to Watch Deep Data Structures in Vue (Arrays and Objects)
    Page: DOMContentLoaded, load, beforeunload, unload
    linux bridge
    linux bridge
    EVE-NG网卡桥接
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CF605E.html
Copyright © 2020-2023  润新知