• 10Day抢救计划


    算是强迫自己复习一次做的题吧


    LuoGu3802 小魔女帕琪

    首先很重要的一点:(1-7)放了大招,可能(2-8)也会放大招。这对接下来的推导过程很重要。

    先求出前(7)次放出大招的概率。

    (sum=sum_{i=1}^{7}a_i),则有:

    (P(7)=frac{a_1}{sum}*frac{a_2}{sum-1}*frac{a_3}{sum-2}*frac{a_4}{sum-3}*frac{a_5}{sum-4}*frac{a_6}{sum-5}*frac{a_7}{sum-6})

    考虑到这种两两不同的出现情况可能是一个全排列,实际上(P(7))应该还要乘上(7!)

    接下来考虑在第(8)次放大的概率。

    令第一个取出来的是(a_1),则有(P(8)=frac{a_1}{sum}*frac{a_2}{sum-1}*frac{a_3}{sum-2}*frac{a_4}{sum-3}*frac{a_5}{sum-4}*frac{a_6}{sum-5}*frac{a_7}{sum-6}*frac{a_1-1}{sum-7})

    这是确定了第一个的,所以第(2-8)个可以任意排列,实际上(P(8))还是要乘上(7!)

    同理,第一个取出来的是(a_2)(a_3)的情况与(a_1)相仿,那么(P(8))的实际大小应该等于(sum_{i=1}^7P'(a_i)),其中(P'(a_i))表示在第一个取出(a_i)的条件下第(8)次放大的概率(条件概率的基本公式)。

    现在考虑和式化简。

    (P(8)=frac{a_1}{sum}*7!*frac{a_1-1}{sum-1}*frac{a_2}{sum-2}*frac{a_3}{sum-3}*frac{a_4}{sum-4}*frac{a_5}{sum-5}*frac{a_6}{sum-6}*frac{a_7}{sum-7})

    (+frac{a_2}{sum}*7!*frac{a_1}{sum-1}*frac{a_2-1}{sum-2}*frac{a_3}{sum-3}*frac{a_4}{sum-4}*frac{a_5}{sum-5}*frac{a_6}{sum-6}*frac{a_7}{sum-7})

    (+...)

    (+frac{a_7}{sum}*7!*frac{a_1}{sum-1}*frac{a_2}{sum-2}*frac{a_3}{sum-3}*frac{a_4}{sum-4}*frac{a_5}{sum-5}*frac{a_6}{sum-6}*frac{a_7-1}{sum-7})

    (K=prod_{i=1}^7a_i),原式化简为:

    (7!/sum/(sum-1)/.../(sum-7)*K*sum_{i=1}^7(a_i-1))

    (=7!/sum/(sum-1)/.../(sum-7)*(sum-7)*K)

    (=7!/sum/(sum-1)/.../(sum-6)*K)

    拆开(K)后有

    (P(8)=frac{a_1}{sum}*frac{a_2}{sum-1}*frac{a_3}{sum-2}*frac{a_4}{sum-3}*frac{a_5}{sum-4}*frac{a_6}{sum-5}*frac{a_7}{sum-6}=P(7))

    也就是第(8)次放大和第(7)次放大的概率是一样的。

    由数学归纳法,易证得(P(i)=P(7),iin[7,sum])

    那就好办了

    int n = 7, sum;
    int a[233];
    int main()
    {
    //	freopen("testdata.in", "r", stdin);
    	for (rg int i = 1; i <= n; ++i) read(a[i]), sum += a[i];
    	if (sum < 7)
    	{
    		printf("0.000");
    		return 0;
    	}
    	rg double ans = 1;
    	for (rg int i = 1; i <= n; ++i) ans *= 1.0 * a[i] / (sum - i + 1);
    	printf("%.3lf", ans * 5040ll * (LL)(sum - 6));
    	return 0;
    }
    

    LuoGu4316 绿豆蛙的归宿

    根据题意,很容易设计出逆推状态:设(dp[i])表示在第(i)点期望多少步走到终点,显然初始状态(dp[n]=0),所求状态(dp[1])

    这里也体现了设计期望(dp)的一般套路:哪个起始状态给定就从哪推 (有可能是我只做了这种简单题)

    我们可以很容易地得到一个状态转移方程如下:

    [dp[u]=frac{1}{degree[u]}*sum_{vin(son(u))}(dp[v]+dis(u,v)) ]

    考虑如何进行转移。

    题目给定原图是一张DAG,很自然地想到拓扑排序。考虑在拓扑排序时更新(dp)值,我们建一张原图的反图,那么就可以很自然地从节点(n)向节点(1)递推了。

    queue<int> q;
    inline void topsort()
    {
    	q.push(n);
    	while (!q.empty())
    	{
    		rg int x = q.front();
    		q.pop();
    		if (memd[x]) dp[x] = dp[x] / (1.0 * memd[x]);
    		for (rg int i = head[x]; i; i = e[i].next)
    		{
    			rg int v = e[i].v, w = e[i].w;
    			dp[v] += dp[x] + w;
    			if (!(--deg[v])) q.push(v); 
    		}
    	}
    }
    int main()
    {
    //	freopen("testdata(1).in", "r", stdin);
    	read(n), read(m);
    	for (rg int i = 1; i <= m; ++i)
    	{
    		read(x), read(y), read(z);
    		add(y, x, z), ++deg[x], ++memd[x];
    	}
    	topsort();
    	printf("%.2lf", dp[1]);
    	return 0;
    }
    

    LuoGu4550 收集邮票

    (dp[i])表示当前收集了(i)种邮票,距离收集所有邮票的期望次数。易知(dp[n]=0)。考虑逆推:

    [dp[i]=dp[i]*frac{i}{n}+dp[i+1]*frac{n-i}{n}+1 ]

    这个转移方程的意思是:当前已收集(i)种邮票,那么有(frac{i}{n})的概率重复收集,有(frac{n-i}{n})的概率收集到新邮票,当然还要加上本次的花费。

    移项,合并同类项后原式化简为:(dp[i]=dp[i+1]+frac{n}{n-i})

    对于本题还不够,这个题还有一个状态:花费。

    由于花费与收集次数有关,那么考虑求出(dp)后用(dp)辅助更新。

    (pd[i])表示当前收集了(i)邮票,距离收集所有邮票的期望花费。易知(pd[n]=0)。依旧考虑逆推:

    [pd[i]=frac{i}{n}*(dp[i]+pd[i]+1)+frac{n-i}{n}*(dp[i+1+pd[i+1]+1) ]

    这个转移方程的意义是:当前已收集(i)种邮票,那么有(frac{i}{n})的概率重复收集,花费是(frac{i}{n}*(dp[i]+pd[i]+1)),有(frac{n-i}{n})的概率收集到新邮票,花费是(frac{n-i}{n}*(dp[i+1+pd[i+1]+1))

    化简后可得:

  • 相关阅读:
    iframe中的页面如何触发父页面事件
    js获取gridview的值
    不出现重复数字,带干扰的验证码
    文本框内不允许输入字母
    后台调用前台JS方法
    在后台得到前台元素,给元素改变属性值或添加属性
    C#常见面试题
    Flex代码生成器 (FCG)
    c#(WinForm)遍历局域网计算机(电脑)获取IP和计算机名称
    VisualSVN Server + Tortoise SVN 使用教程(补充版)
  • 原文地址:https://www.cnblogs.com/Here-is-SG/p/11853792.html
Copyright © 2020-2023  润新知