• 洛谷 P4550 收集邮票


    洛谷 P4550 收集邮票

    题目链接:洛谷 P4550 收集邮票

    算法标签: 动态规划(DP)期望DP

    题目

    题目描述

    有n种不同的邮票,皮皮想收集所有种类的邮票。唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且买到的邮票究竟是n种邮票中的哪一种是等概率的,概率均为1/n。但是由于凡凡也很喜欢邮票,所以皮皮购买第k张邮票需要支付k元钱。
    现在皮皮手中没有邮票,皮皮想知道自己得到所有种类的邮票需要花费的钱数目的期望。

    输入格式

    一行,一个数字N
    N<=10000

    输出格式

    要付出多少钱.
    保留二位小数

    输入输出样例

    输入 #1

    3
    

    输出 #1

    21.25
    

    题解:

    期望DP

    按照题目的描述,我们可以设一个(f[])和一个(g[])

    (f[i])表示买到第(i)张邮票还需要购买的期望次数

    (g[i])表示买到第(i)张邮票还需要期望花费的钱数。

    讲到这里大概就可以发现,这道题需要逆推

    对于一个(f[i]),我们也可以有以下的几种方案:

    ​ 会买到重复邮票的概率为(frac{i}{n}),所以这项贡献:(f[i] imes frac{i}{n})

    ​ 会买到不同邮票的概率为(frac{n - i}{n}),所以这项贡献:(f[i+1] imes frac{n-i}{n})

    ​ 买当前邮票,贡献为:(1)

    所以对于一个(f[i]),我们可以得出:(f[i]=f[i] imes frac{i}{n} + f[i+1] imes frac{n-i}{n}+1)

    化简得出:(f[i] = f[i + 1] + frac{n}{n-i} dots ①)

    那么对于(g[i]),推导的方式大致与(f[i])类似:

    (g[i] = (f[i]+g[i]+1) imes frac{i}{n}+(f[i+1]+g[i+1]+1) imesfrac{n-i}{n})

    化简得出:(g[i]=frac{i}{n-i} imes f[i]+f[i+1]+g[i+1]+frac{n}{n-i} dots ②)

    至此,两个必要的递推式都推导完毕,接下来就是注意好double的处理,输入和输出,计算等等即可。

    AC代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 10010;
    
    int n;
    
    double f[N], g[N];
    
    double _div(int a, int b)
    {
    	return a * 1.00 / b * 1.00;
    }
    
    int main()
    {
    	scanf("%d", &n);
    	f[n] = g[n] = 0;
    	for (int i = n - 1; i >= 0; i -- )
    	{
    		f[i] = f[i + 1] + _div(n, n - i);
    		g[i] = _div(i, n - i) * f[i] + f[i + 1] + g[i + 1] + _div(n, n - i);
    	}
    	printf("%.2lf", g[0]);
    }
    
  • 相关阅读:
    [湖南集训]谈笑风生
    【SCOI2010】序列操作
    ●BZOJ 3994 [SDOI2015]约数个数和
    ●BZOJ 3309 DZY Loves Math
    ●UOJ 21 缩进优化
    ●BZOJ 2693 jzptab
    ●BZOJ 2154 Crash的数字表格
    ●BZOJ 3529 [Sdoi2014]数表
    ●2301 [HAOI2011] Problem b
    ●BZOJ 2820 YY的GCD
  • 原文地址:https://www.cnblogs.com/littleseven777/p/11841572.html
Copyright © 2020-2023  润新知