HDU 4986/BC 7B Little Pony and Alohomora Part I

来源:互联网 发布:二手车 知乎 编辑:程序博客网 时间:2024/05/21 10:25

题目大意:n个箱子,每个箱子一把钥匙,随机放在一个箱子里,现在你要打开所有箱子,求要用开箱魔法(不用钥匙也能开箱子)的次数期望。

先不考虑过大的n尝试用 dp去解,

设有1,2,3...n

随机选取出一个箱子先开,这里假设选1,

1箱中有2种可能  1/n的可能 装着 钥匙1 这时 dp[i]=(dp[i-1]+1)/n。

 第二种 n-1/n的可能 假设装着钥匙2 这时  2箱子已不能装钥匙2(因为被1选了)但1钥匙 和其他钥匙的选择导致的状态无法判断是否平等

所以把这状态写为f(1,n-2) 表示 2箱子可能装的钥匙  前者表示2箱子可以装的已经开过的箱子的钥匙数量  后者表示2箱子可以装的没开过箱子的钥匙数目

 dp[i]=f(1,n-2)*(n-1)/n。

现在我们对f(1,n-2)进行分析,有选1时 状态f(1,n-2)=(dp[i-2]+1)/(n-1)。

选n-2时 假设选了3  这时箱子3 不可以选钥匙2 和钥匙3  只能是选钥匙1 或其他n-3个钥匙  有 f(1,n-2)= f(1,n-3)*(n-2)/(n-1)。

而这个f(1,n-2) 跟的d[i-1]的方程是一模一样的 ,所以有f(1,n-2)=d[i-1]。dp[i]=(dp[i-1]+1)/n+d[i-1]*(n-1)/n=d[i-1]+1/n。

所以 从1开始 不断增加 1/2、1/3、1/4等等。

当然你手推出3 和4 的情况 自己猜一下规律也猜的出来,可靠规律做这题就一点意义都没有了,你在百度下调和级数,这题就白做了。如果这种题都靠规律来做,等到真正难的题,没有规律了,你没有养成好的思考习惯,肯定是出不出来的。

现在前面的结论得出了,不管你是找规律还是推出来,都要面临一个新的问题,n太大了怎么处理,手推没有发现很好的公式,有人直接就去百度了,但这样不锻炼思维,等到比赛时没有百度怎么办呢? 所以我试着找规律 开始想他会不会后来就不涨了 打表后发现只是涨的缓慢,于是就开始跟根号n和log2 做差什么的,最后发现 和loge(n)的差值十分稳定,大概在0.57722左右,后来才知道这叫调和级数 欧拉发现的

#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <queue>#include <map>#include<stack>#include<bitset>#define inf 0x3f3f3f3f#define ll long long#define mod 1000000007using namespace std;#define bug puts("bugbugubgbugbug");int main(){    int n;    while(~scanf("%d",&n))    {        if(n>=1000000)         printf("%.4lf\n",log((double)n)+0.57722);        else{        double ans=0;        for(int i=1;i<=n;i++)        {            double j=i;            ans+=1/j;        }        printf("%.4lf\n",ans);        }    }    return 0;}


0 0