zoukankan      html  css  js  c++  java
  • UVA

    Dilu have learned a new thing about integers, which is - any positive integer greater than 1 can be
    divided by at least one prime number less than or equal to that number. So, he is now playing with
    this property. He selects a number N. And he calls this D.
    In each turn he randomly chooses a prime number less than or equal to D. If D is divisible by the
    prime number then he divides D by the prime number to obtain new D. Otherwise he keeps the old
    D. He repeats this procedure until D becomes 1. What is the expected number of moves required for
    N to become 1.
    [We say that an integer is said to be prime if its divisible by exactly two different integers. So, 1 is not
    a prime, by definition. List of first few primes are 2, 3, 5, 7, 11, ...]
    Input
    Input will start with an integer T (T ≤ 1000), which indicates the number of test cases. Each of the
    next T lines will contain one integer N (1 ≤ N ≤ 1000000).
    Output
    For each test case output a single line giving the case number followed by the expected number of turn
    required. Errors up to 1e-6 will be accepted.
    Sample Input
    3
    1
    3
    13
    Sample Output
    Case 1: 0.0000000000
    Case 2: 2.0000000000
    Case 3: 6.0000000000

    题意:给出一个整数N,每次可以在不超过N的素数中随机选择一个P,如果P是N的约数,则把N变成N/P,否则N不变。问平均情况下需要多少次选择,才能把N变成1.

    题解:记录dp[n] 表示 N = n是答案是多少

       dp[n] = 1 +  ∑dp[素数因子] *  1/素数总和  +   ∑dp[x] * (x为非因子素数)/ 素数总和

          记忆化爆搜就可以

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std ;
    typedef long long ll;
    
    const int N=1000000;
    
    int H[N + 5],P[N],cnt,vis[N + 5];
    double dp[N + 6];
    void prime_table() {
        H[1] = 1;
        for(int i = 2 ; i <= N ; i++) {
            if(!H[i]) {
                P[++cnt] = i;
                for(int j = 2 * i ; j <= N ; j += i) H[j] = 1;
            }
        }
    }
    double dfs(int n) {
        if(vis[n]) return dp[n];
        if(n == 1) return dp[n] = 0;
        double& ans = dp[n];
        int sum = 0, g = 0;
        vis[n] = 1;
        for(int i = 1 ; i <= cnt && P[i] <= n; i++) {
            sum ++;
            if(n % P[i] == 0) {
                ans += dfs(n / P[i]);
            }else g++;
        }
        return ans = (ans + sum) / (sum - g);
    }
    int main () {
        cnt = 0;
        prime_table();
        int T, cas = 1, n;
        scanf("%d",&T);
        while(T--) {
            scanf("%d",&n);
            dfs(n);
            printf("Case %d: %.10f
    ", cas++, dp[n]);
        }
        return 0;
    }
    代码
  • 相关阅读:
    Web安全实践
    认证授权的设计与实现
    Elasticsearch 分页查询
    【算法】三色旗
    【转】互联网项目中mysql应该选什么事务隔离级别
    Elasticsearch 聚合
    Elasticsearch 结构化搜索、keyword、Term查询
    Elasticsearch 单字符串多字段查询
    Elasticsearch 复合查询——多字符串多字段查询
    JavaScript 原型与原型链
  • 原文地址:https://www.cnblogs.com/zxhl/p/5122799.html
Copyright © 2011-2022 走看看