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;
    }
    
    
    
    
    
    
    
    
  • 相关阅读:
    【题解】[湖南集训]谈笑风生
    【题解】[POI2011]ROT-Tree Rotations
    【题解】[ZJOI2019]语言
    【题解】[HEOI2012]采花
    【题解】[JSOI2009]计数问题
    【题解】[USACO17JAN]Promotion Counting P
    heketi简单安装配置使用
    kubernetes api
    skywalking简单安装配置使用
    《技术的正宗与野路子》
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13215989.html
Copyright © 2011-2022 走看看