Description
有
n
种不同的邮票,皮皮想收集所有种类的邮票。唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且买到的邮票究竟是
Input
一行,一个数字
N(N<=10000)
Output
要付出多少钱. 保留二位小数
Sample Input
3
Sample Output
21.25
HINT
Source
思路
令
gi
表示前
i
种邮票都获得后还需要多少张邮票才能凑齐
gi=in∗gi+n−in∗gi+1+1
化简:
gi−in∗gi=n−in∗gi+1+1
n−in∗gi=n−in∗gi+1+1
gi=gi+1+nn−i
但是这个有什么用呢?先不管,设 fi 表示前 i 种邮票都获得后还需要付多少元钱才能集齐
fi=in∗(fi+gi)+n−in∗(fi+1+gi+1)+1
理由?由于是从后往前推
f
和那么将这个式子化简,得:
fi−in∗fi=in∗gi+n−in∗(fi+1+gi+1)+1
n−in∗fi=in∗gi+n−in∗(fi+1+gi+1)+1
fi=in−i∗gi+fi+1+gi+1+nn−i
最终输出
f0
即可。
最后吐槽一句:代码量真少,思维量真多啊。
代码
#include <cstdio>
const int maxn=10000;
double f[maxn+10],g[maxn+10];
int n;
int main()
{
scanf("%d",&n);
for(int i=n-1; i>=0; i--)
{
g[i]=g[i+1]+(double)n/(n-i);
//求g数组的值
}
for(int i=n-1; i>=0; i--)
{
f[i]=g[i]*i/(n-i)+f[i+1]+g[i+1]+(double)n/(n-i);
//求f数组的值
}
printf("%.2lf\n",f[0]);
return 0;
}