就是状态转移是有概率的,但要求的是期望,那就用全期望公式写出状态转移方程就好了,这个状态机有些有趣,就是一定概率变成自己,所以写出出全期望公式后变形一下就是状态转移方程,然后正常的记忆化搜索就好了。画出状态转移图有助于写出正确的公式。在动态规划里状态转移方程就是一切,写错一点就什么都没了。画图是个不错的辅助技巧。写出公式后一定要化简,这甚至可能是最关键的一步。
代码
#include<bits/stdc++.h>
#define maxn 1000010
using namespace std;
int vis[maxn];
vector<int>prm;
void init()
{
int m=sqrt(1e6+0.5);
for(int i=2;i<=m;i++) if(!vis[i])
for(int j=i*i;j<=1e6;j+=i)
vis[j]=true;
for(int i=2;i<=1e6;i++)
if(!vis[i])
prm.push_back(i);
memset(vis,0,sizeof(vis));
}
double dp[maxn];
double d(int n)
{
double& ans=dp[n];
if(vis[n]) return ans;
vis[n]=1;
if(n==1) return ans=0;
int p=0,g=0;
for(unsigned int i=0;i<prm.size();i++)
if(prm[i]>n) break;
else
{
p++;
if(n%prm[i]==0)
{
dp[n]+=d(n/prm[i]);
g++;
}
}
return ans=(ans+p)/g;
}
int main()
{
init();
int T;
scanf("%d",&T);
for(int t=1;t<=T;t++)
{
int N;
scanf("%d",&N);
printf("Case %d: %lf\n",t,d(N));
}
return 0;
}