您的位置:首页 > 大数据 > 人工智能

LightOJ - 1038 Race to 1 Again 递推+期望

2015-06-04 14:46 357 查看
题目大意:给出一个数,要求你按一定的规则将这个数变成1

规则如下,假设该数为D,要求你在[1,D]之间选出D的因子,用D除上这个因子,然后继续按该规则运算,直到该数变成1

问变成1的期望步数是多少

解题思路:递推,设该数为D,有N个因子,分别是1,n1,n2,n3…nn-2,D,

那么选到每个因子的概率都是1/N,除非选到D,不然选到其他因子的话都要多1步,然后再计算D除以该因子的期望

这就能得到公式了,设dp[D]为数D按规则变成1的期望步数

那么dp[D] = 1/N * (dp[D/1] + 1) + 1 / N * (dp[D/n1] + 1) + 1/ N * (dp[D/n2] + 1) + … + 1/N * (dp[D/nn-2] + 1) + 1/N * (dp[D / D] + 1)

化简得 dp[D] = 1 / (N-1) * (dp[D/n1] + dp[D/n2] + … + dp[D/nn-2] + N)

[code]#include<cstdio>
#include<cstring>
#include<cmath>
#define maxn 100010
double dp[maxn];

void init() {
    dp[1] = double(0);

    for(int i = 2; i <= 1e5; i++) {
        int cnt = 0;
        dp[i] = 0.0;
        for(int j = 1; j * j <= i; j++) {
            if(i % j == 0 && i / j != j) {
                cnt += 2;
                dp[i] += dp[j] + dp[i / j] + 2; 
            }
            if(j * j == i) {
                cnt += 1;
                dp[i] += dp[j] + 1;
            }
        }
        dp[i] /= (cnt - 1);
    }
}

int main() {
    init();
    int test, cas = 1, n;
    scanf("%d", &test);
    while(test--) {
        scanf("%d", &n);
        printf("Case %d: %.10lf\n", cas++, dp
);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: