bzoj 5094 [Lydsy1711月赛]硬盘检测 概率dp

 [Lydsy1711月赛]硬盘检测

Time Limit: 1 Sec  Memory Limit: 256 MB
Submit: 273  Solved: 75
[Submit][Status][Discuss]

Description

很久很久以前,小Q买了一个大小为n单元的硬盘,并往里随机写入了n个32位无符号整数。因为时间过去太久,硬
盘上的容量字眼早已模糊不清,小Q也早已忘记了硬盘的容量。小Q记得,n可以被表示成10^k(1<=k<=7)的形式,即
十到一千万。他还记得自己曾经m次随机读取某个32位无符号整数的记录。小Q现在正在Quapler宇宙飞船上遨游WF1
8星座,所以他想请你帮他找出n的具体大小。
 

Input

第一行包含一个正整数m(m=10000),表示随机访问硬盘的次数。

接下来m行,每行一个整数a_i(0<=a_i<2^{32}),即每次随机访问读取的结果。
 

Output

 输出一行一个整数,即n的大小。

 

Sample Input

15
2743802941
2520732963
3408553159
1132588462
2520732963
1252627160
2963673642
3972869548
2743802941
684663103
2743802941
3972869548
2520732963
1252627160
1252627160

Sample Output

10

HINT

 

Source

 
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <map>
 5 #include <cmath>
 6  
 7 using namespace std;
 8 int m,tot,ans;
 9 double mx,sum;
10 map<int,int> s;
11 int cnt[10010];
12 double jc[10010];
13 inline double c(int a,int b)
14 {
15     if(a<b)  return -1e10;
16     return jc[a]-jc[a-b]-jc[b];
17 }
18 inline int rd()
19 {
20     int ret=0,f=1;  char gc=getchar();
21     while(gc<'0'||gc>'9') {if(gc=='-')    f=-f;   gc=getchar();}
22     while(gc>='0'&&gc<='9')   ret=ret*10+(gc^'0'),gc=getchar();
23     return ret*f;
24 }
25 int main()
26 {
27     m=rd();
28     register int n,i,a,tmp;
29     for(i=1;i<=m;i++)
30     {
31         a=rd();
32         if(!s[a])   s[a]=++tot;
33         cnt[s[a]]++;
34     }
35     mx=-1e10;
36     for(i=1;i<=m;i++)    jc[i]=jc[i-1]+log(i);
37     for(n=10;n<=10000000;n*=10)
38     {
39         if(n<tot)    continue;
40         sum=0;
41         for(i=1;i<=tot;i++)  sum+=log(n-i+1)-log(i);
42         sum+=-log(n)*m,tmp=m;
43         for(i=1;i<=tot;i++)  sum+=c(tmp,cnt[i]),tmp-=cnt[i];
44         if(sum>mx)   mx=sum,ans=n;
45     }
46     printf("%d",ans);
47 }
原文地址:https://www.cnblogs.com/fengzhiyuan/p/8659125.html