1. 程式人生 > >lightoj1038(數學概率與期望)

lightoj1038(數學概率與期望)

每次 iostream ios 輸入一個數 esp pac lightoj size fin

題意:輸入一個數N,N每次被它的任意一個因數所除 變成新的N 這樣一直除下去 直到 N變為1

求變成1所期望的次數

解析:

d[i] 代表從i除到1的期望步數;那麽假設i一共有c個因子(包括1和本身)

d[i] = ( d[1] + d[a2] + d[a3] + d[a4] ..... + d[i] + c) / c; (加c是因為每一個期望值都會加1,因為多出一步才變成它(即第一次從i到它的因子的那一步))

把右邊的dp[i] 移到左邊 化簡得

dp[i] = ( d[1] + d[a2] + d[a3] + d[a4] ..... + d[i-1] + c) / (c-1)

註意:不能太暴力求因數,折半求 還有。。。。mmp。。不要用Java做。。。。

這一題與lightoj1030 的思路一樣 都是期望dp

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = 100005;
int cnt;
int main() {
    int res = 0;
    double dp[maxn];
    mem(dp,0);
    int temp;
    
for(int i=2;i<maxn;i++) { cnt = 0; double sum = 0; for(int j=1;j<=sqrt(i+0.5);j++) { if(i % j == 0) { sum += dp[j]; cnt++; if(j != i/j){ sum += dp[i/j]; cnt
++; } } } dp[i] = (sum + cnt)/(double)(cnt-1); } int T; scanf("%d",&T); while(T--) { scanf("%d",&temp); printf("Case %d: %.10f\n",++res,dp[temp]); } return 0; }

lightoj1038(數學概率與期望)