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

23 篇文章 0 订阅

题目大意: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 1000000007
using 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值