• 【HDU】4089 Activation


    http://acm.hdu.edu.cn/showproblem.php?pid=4089

    题意:

    有n个人排队等着在官网上激活游戏。主角排在第m个。

    对于队列中的第一个人。有以下情况:
    1、激活失败,留在队列中等待下一次激活(概率为p1)
    2、失去连接,出队列,然后排在队列的最后(概率为p2)
    3、激活成功,离开队列(概率为p3)
    4、服务器瘫痪,服务器停止激活,所有人都无法激活了。

    求服务器瘫痪时主角在队列中的位置<=k的概率

    n, m<=1000, p1+p2+p3+p4=1

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=10005;
    const double eps=1e-10;
    double c[N], T1[N], T2[N], p[5], T;
    int n, m, K;
    double abs(double x) { return x<0?-x:x; }
    int main() {
    	while(~scanf("%d%d%d", &n, &m, &K)) {
    		for(int i=1; i<=4; ++i) scanf("%lf", &p[i]);
    		if(abs(p[4])<eps) { puts("0.00000"); continue; }
    		double *now=T1, *last=T2, di=1-p[1];
    		T=p[2]/di;
    		for(int i=1; i<=n; ++i) {
    			c[1]=p[4]/di;
    			for(int j=2, g=min(K, i); j<=g; ++j) c[j]=(last[j-1]*p[3]+p[4])/di;
    			for(int j=K+1; j<=i; ++j) c[j]=last[j-1]*p[3]/di;
    			double up=0, down=1;
    			for(int j=1; j<=i; ++j) down*=T, up*=T, up+=c[j];
    			now[i]=up/(1-down);
    			now[1]=T*now[i]+c[1];
    			for(int j=2; j<=i; ++j) now[j]=T*now[j-1]+c[j];
    			swap(now, last);
    		}
    		printf("%.5f
    ", last[m]);
    		memset(T2, 0, sizeof(double)*(n+1));
    	}
    	return 0;
    }
    

      

    做完这题深深感到了数学题与编程题不同= =...

    首先容易设计出$d[i][j]$表示一共还有i个人,主角排在了$j$位(反正一开始我没考虑到人总数对方程的影响妈呀QAQ果然还是太弱么...

    容易得到:

    $$
    egin{align}
    d[i][1] & = d[i][1]p1 + d[i][i]p2 + p4 & j==1时 \
    d[i][j] & = d[i][j]p1 + d[i][j-1]p2 + d[i-1][j-1]p3 + p4 & j<=k时 \
    d[i][j] & = (d[i][j-1]p2 + d[i-1][j-1]p3)/(1-p1) & k<j时
    end{align}
    $$

    深度化简可以得到:

    $$
    egin{align}
    d[i][1] & = Td[i][i] + c[1] & j==1时\
    d[i][j] & = Td[i][j-1] + c[j] & j<=k时\
    d[i][j] & = Td[i][j-1] + c[j] & k<j时
    end{align}
    $$

    其中$T=p2/(1-p1)$, $c[j]$为那些常数项(因为$d[i-1]$的部分已经求出来了,现在只是考虑互相关系的$d[i]$,所以把$d[i-1]$看成常数)

    那么这成了递归定义,发现我没只需要求出$d[i][i]$就行了...

    一直递归下去可以发现,$d[i][i]=T(T(T(...Td[i][i]+c[1])+c[2])+c[3])+...+c[i]$

    所以$d[i][i]=C/(1-T^i), C=T(T...T0+c[1])+c[2]+...+c[i]$

    最后还要特判$p4=0$的情况啊,显然答案是0啊..(可是我发现我的程序对p4=0的情况已经免疫了啊?为啥还会waQAQ不明觉厉..反正特判一下就能对QAQ)

  • 相关阅读:
    Easy | LeetCode 108. 将有序数组转换为二叉搜索树
    Medium | LeetCode 105 | 剑指 Offer 07. 从前序与中序遍历序列构造二叉树
    Easy | LeetCode 543. 二叉树的直径
    Easy | LeetCode 235 | 剑指 Offer 68
    Easy | LeetCode 236 | 剑指 Offer 68
    Medium | LeetCode 114. 二叉树展开为链表 | 先序遍历 | 递归 | 迭代
    Medium | LeetCode 538,1038. 把二叉搜索树转换为累加树
    Medium | LeetCode 230. 二叉搜索树中第K小的元素
    Easy | 剑指 Offer 54. 二叉搜索树的第k大节点
    stl(5)vector容器
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4298269.html
Copyright © 2020-2023  润新知