zoukankan      html  css  js  c++  java
  • LightOJ

    题意:

      给定一个数字N,每次可以用自身的因子来对自身进行分解,问将N分解为1所需分解次数的数学期望。

      (给个数字D,我们可以选择1~D中可以被D整除的因子,除以D得到一个新的D,再用新D除以它的因子得到又一个新D,按次操作除到D=1时结束,求除的次数的期望值。)

    解题思路:

      定义:

      D(N):将N分解为1所需要的分解次数。

      E(N)=E(D(N)):将N分解为1所需分解次数的数学期望。

      对分解类型问题的首先想到能否对问题进行约归,即将问题转化成规模更小的问题,即考虑E(N)与E(X)(X<N)之间的关系。

      设N的因子个数为cnt,分别记为a1,a2,a3,……,第一次对N进行分解,可选的因子个数为cnt,且每个被选中的概率相等,又用一个因子a对N进行分解,N会变为另一个因子b(a*b=N),所以第一次对N进行分解后N会变为自身的某个因子,且变为每个因子的概率相等。

      于是根据类似于全概率公式的思想:

     ,设acnt=N;化简可得

      

       再根据期望公式E(A+B)=E(A)+E(B);

      

      所以为求得E(N),我们先求得所有E(X)(X<N ),然后再根据N的所有因子来计算E(N)。

       再考虑类似与筛法的思想,求的N的因子比较费事,但求的X是谁的因子非常简单,X是X*1,X*2,X*3....的因子。

      所以我们可以按从小到达顺序,将E(a)的值加到它的倍数上,这样当遇到N的只需要(E(N)+cnt)/(cnt-1)就可以计算出E(N)。

      N的cnt怎么计算,每有一个E(a)加到了N身上,N的cnt值就++。

    核心思想:

      变量分解,DP,筛法。

    #include<iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    const int MAXN=1e5+1;
    double dp[MAXN];
    int cnt[MAXN];
    void pre(){
        for(int i=2;i<MAXN;i++){
            cnt[i]+=2;
            dp[i]+=cnt[i];
            dp[i]/=(cnt[i]-1);
            for(int j=2;i*j<MAXN;j++){
                dp[i*j]+=dp[i];
                cnt[i*j]++;
            }
        }
    }
    int main(){
        int T;
        scanf("%d",&T);
        int tmp;
        pre();
        for(int tt=1;tt<=T;tt++){
            scanf("%d",&tmp);
            printf("Case %d: %.7f
    ",tt,dp[tmp]);
        }
    }
    View Code

       

      

  • 相关阅读:
    [LeetCode] Add Two Numbers
    [LeetCode] Two Sum
    解决 wget 使用 https 下载报错的问题
    VMware Player 使用笔记
    使用 linux 作为桌面系统会遇到的一些小问题和解决方案
    CUDA 6.5 + Visual Studio 2013 Express 环境配置
    康威生命游戏(Conway's Game of Life)的一种实现
    微软校招编程题"Beautiful String"的状态机解法
    利用html5的本地存储写的一个购物车
    微信开发asp.net
  • 原文地址:https://www.cnblogs.com/dialectics/p/12447949.html
Copyright © 2011-2022 走看看