
题意:输入一个数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 = ;
int cnt;
int main() {
int res = ;
double dp[maxn];
mem(dp,);
int temp;
for(int i=;i<maxn;i++)
{
cnt = ;
double sum = ;
for(int j=;j<=sqrt(i+0.5);j++)
{
if(i % j == )
{
sum += dp[j];
cnt++;
if(j != i/j){
sum += dp[i/j];
cnt++;
}
} }
dp[i] = (sum + cnt)/(double)(cnt-);
}
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&temp);
printf("Case %d: %.10f\n",++res,dp[temp]);
} return ;
}