zoukankan      html  css  js  c++  java
  • [LnOI2019]加特林轮盘赌

    VI.[LnOI2019]加特林轮盘赌

    我们考虑设\(f[i][j]\)表示\(i\)个人中,第\(j\)个人最终存活的概率。

    我们先考虑\(j>1\)的情况。此时,有\(p\)的概率排在首位的人挂掉,局面变为\(f[i-1][j-1]\);反之,有\(1-p\)的概率首位存活,这就相当于所有人向前进一格,局面变为\(f[i][j-1]\)

    于是我们有

    \[f[i][j]=p\times f[i-1][j-1]+(1-p)\times f[i][j-1]\qquad(1<j\leq i) \]

    下面我们考虑特殊情况\(f[i][1]\)。显然,只有这一枪他幸存下来了,他最终才有可能存活。故我们有

    \[f[i][1]=(1-p)f[i][i] \]

    到这里我们就可以DP了。我们初始有\(f[1][1]=1\);接着,我们从小往大枚举\(i\),更新DP状态。

    我们设\(f[i][1]=a\times f[i][i]+b\)。显然,此时有\(a=1-p,b=0\)。这样,我们就可以把\(f[i][2]\)表示成\(c\times f[i][i]+d\)的形式,接着把\(f[i][3]\)表示成\(e\times f[i][i]+f\)的形式……

    最终,我们得到一个方程:

    \[f[i][i]=x\times f[i][i]+y \]

    直接解该方程即可得出\(f[i][i]\)。再DP一圈即可得出所有的\(f[i][j]\)

    时间复杂度\(O(n^2)\)。(注意特判\(p=0\)时的情况)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const long double eps=1e-9;
    int n,m;
    long double p,f[2][10100];
    int main(){
    	cin>>p>>n>>m;
    	if(p<eps){if(m==1)puts("1");else puts("0");return 0;}
    	f[1][1]=1;
    	for(int i=2;i<=n;i++){
    		double a=1,b=0;
    		for(int j=1;j<=i;j++)a*=1-p,b=(1-p)*b+p*f[!(i&1)][j-1];
    		f[i&1][i]=b/(1-a);
    		f[i&1][1]=(1-p)*f[i&1][i];
    		for(int j=2;j<i;j++)f[i&1][j]=(1-p)*f[i&1][j-1]+p*f[!(i&1)][j-1];
    	}
    	printf("%.10Lf\n",f[n&1][m]);
    	return 0;
    } 
    

  • 相关阅读:
    Leetcode Unique Binary Search Trees
    Leetcode Decode Ways
    Leetcode Range Sum Query 2D
    Leetcode Range Sum Query
    Leetcode Swap Nodes in Pairs
    Leetcode Rotate Image
    Leetcode Game of Life
    Leetcode Set Matrix Zeroes
    Leetcode Linked List Cycle II
    CF1321A
  • 原文地址:https://www.cnblogs.com/Troverld/p/14610869.html
Copyright © 2011-2022 走看看