zoukankan      html  css  js  c++  java
  • LightOJ

    题意:Rimi学到了一个关于整数的知识,就是任何大于1的整数可以被它的任何因子整除。所以,他准备玩这个特性。他选择了一个整数N,每一次,他随机的选择这个整数的因子,并且整除这个数。直到使得这个数变成1。求N到1的期望值。

    分析:一个数可以被它的因子整除,那么整除完的新值也是它的因子。我们定义f[i]:i到1的期望值,那么(f[i] = (f[num[1]] + 1 + f[num[2]] + 1 + f[num[3]] + 1 + ... + f[num[n]] + 1) / num,)num[]数组是i的因子数组,我们可以得出num[n] = i,所以我们可以化简如下:

    (f[i] * num = f[num[1]] + f[num[2]] + f[num[3]] + ... + f[num[n]] + num)
    (f[i] * (num - 1) = f[num[1]] + f[num[2]] + f[num[3]] + ... + num)
    (f[i] = frac{f[num[1]] + f[num[2]] + f[num[3]] + ...}{num - 1})

    这道题的数N很大,不能使用记忆化搜索,因为记忆化搜索不能把所有的状态搜到,所以要预处理出所有的值。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    const int N = 100005;
    double f[N];
    vector<int> v[N];
    
    int main()
    {
        int t;
        scanf("%d", &t);
    
        //预处理出所有因子
        for(int i = 2; i < N; ++i)
            for(int j = 1; j <= i / j; ++j)
            {
                if(i % j == 0)
                {
                    v[i].push_back(j);
                    if(j * j != i) v[i].push_back(i / j);
                }
            }
        for(int i = 2; i < N; ++i)
        {
            int sz = v[i].size();
            for(int j = 0; j < sz; ++j)
            {
                if(v[i][j] != i) f[i] += f[v[i][j]];
            }
            f[i] = (f[i] + sz) / (sz - 1);
        }
        int c = 0;
        while(t--)
        {
            int n;
            scanf("%d", &n);
            printf("Case %d: %.6lf
    ", ++c, f[n]);
        }
        return 0;
    }
    
    
    
    
    
    
    
    
  • 相关阅读:
    51nod_1445 变色DNA 最短路模板 奇妙思维
    51nod_1459 最短路 dijkstra 特调参数
    UVA_10653 公主与王子 #刘汝佳DP题刷完计划
    HOJ 13819 Height map
    51nod_1255字典序最小的子序列
    电梯设计需求调研报告
    梦断代码读后感
    求一循环数组的最大子数组的和
    求二维数组中最大子数组的和
    四则运算
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13215989.html
Copyright © 2011-2022 走看看