bzoj 5094: 硬盘检测

题解

考虑到n取值个数很小。。
于是我们可以直接枚举n
然后算一下在这个n里面,出现这些东西的概率。。
取概率最大的就可以了

然后计算的时候,由于方案数巨大。。于是我们可以使用对数
————CQ zhangyu

CODE:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<map>
#include<cmath>
using namespace std;
typedef long long LL;
const LL N=100005;
LL m;
map<int,int> o;
LL cnt[N],cnt1;
double mx;
LL ans;
double jc[N];
double C (LL x,LL y)//在y个里面选择x个 
{
    return jc[y]-jc[y-x]-jc[x];
}
int main()
{
    scanf("%lld",&m);
    for (LL u=1;u<=m;u++)
    {
        LL x;
        scanf("%lld",&x);
        if (o[x]==0) o[x]=++cnt1;
        cnt[o[x]]++;
    }
    mx=-1e10;
    for (LL u=1;u<=m;u++) jc[u]=jc[u-1]+log(u);
    for (LL n=10;n<=10000000;n*=10)
    {
        if (n<cnt1) continue;
        double sum=0;
        for (LL u=1;u<=cnt1;u++) sum=sum+log(n-u+1)-log(u);
        sum=sum-log(n)*m;
        LL lalal=m;
        for (LL u=1;u<=cnt1;u++)
        {
            sum=sum+C(cnt[u],lalal);
            lalal=lalal-cnt[u];
        }
        if (sum>mx)
        {
            mx=sum;
            ans=n;
        }
    }
    printf("%lld\n",ans);
    return 0;
}
相关文章
相关标签/搜索