ZZULI 1906: 小火山的幸运数字
2016-09-20 22:35
190 查看
1906: 小火山的幸运数字
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 26 Solved: 11
SubmitStatusWeb
Board
Description
单纯的小火山特别喜欢单纯的事物, 每看到一些东西都想让他们变得单纯起来。现在,单纯的小火山开始学数字了, 看到一串串数字, 小火山觉得自己都不单纯了。
小火山只喜欢单纯的数字1,看到其他数字都要强迫性的将他们变成1。小火山改变数字的规则是这样的:
对于一个数字n,通过随机除以n的约数(约数包含1和n),让n变成一个更小的数(包括n)。
小火山想知道,将这个数字变成1需要变化次数的期望是多少?
Input
输入第一行是一个整数T(T <= 1000), 表示一共有T组数据。每一组数据,包含一个整数N(1 <= N <= 100000)。
Output
每一组数据输出一个数字,表示N变成1的期望次数, 结果保留两位小数。Sample Input
31
2
50
Sample Output
0.002.00
3.03
期望的第一道题 有点懵大神题解
定义f[i] := i变为1的期望次数设i的约数的个数为c,每个约数为a[i] (i <= 1 <= c)
i每次可以除以任意一个约数,而且每个约数选到的概率为1/c
因此f[i] = segma( 1/c * (f[ i / a[i] ] + 1) )
但当a[i] = 1时,等式右边又会出现f[i],将右边的f[i]移到左边,然后解出f[i]
f[1] = 0,每一个i枚举约数的复杂度O(sqrt(i)),总复杂度O(n * sqrt(n))
我的AC代码
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "cmath"
using namespace std;
int a[100010];
double dp[100010];//代表i的期望 平均需要多少次变成1
int main(){
dp[1]=0;
for(int i=2;i<=100000;i++){
int c=0;
for(int j=1;j<=sqrt(i);j++){
if(i%j==0){
int x=i/j;
if(x!=j){
a[++c]=x; a[++c]=j;
}
else{
a[++c]=j;
}
}
}
// a[++c]=i;
double sum=0; double t=1; double l=1.0/c;
for(int j=1;j<=c;j++){
if(a[j]==1){
t=t-l; sum=sum+l;
}
else
sum=sum+ ( l * (dp[i/a[j]]+1));//选取一个的概率是1/c 然后称期望数+1
}
dp[i]=sum/t;
// printf("%lf %lf %d\n",dp[i],t,c);
}
int T; scanf("%d",&T);
while(T--){
int n; scanf("%d",&n); printf("%.2lf\n",dp
);
}
return 0;
}
相关文章推荐
- linux w3m命令
- 每日一题_JavaScript.两种方式实现网页加载后onload绑定多个函数?
- 253_在TextView中换行和打双引号
- 策略模式
- POJ1163Triangle
- python基础(3)—— 程序结构
- python基础(3)—— 程序结构
- mysql添加外键
- python基础(2)—— 基本概念
- response.setHeader()的用法
- 252_自定义单例的Application
- 关于Sublime安装packaga control
- VC6.0打开或者添加工程文件崩溃的解决方法
- python基础(1)——简介与安装
- mysql导入数据load data infile用法整理
- C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区
- 在Centos7上安装mongodb-linux-i686-2.6.7.tgz
- C语言小知识点 汇总2
- SQL中Where与Having的区别
- 待学习的论文