【SCOI2009】游戏
题目
略
解题思路
\(DP\)
根据题意,可以发现N个数可以组成若干个环
设组成了\(K\)个环,每个环的长度为\(L_i\),设\(lcm(l_1,l_2,...,l_k)\)为A,对A分解质因数,\(A=p_{1}^{c_{1}}*p_{2}^{c_{2}}*...*p_{K}^{c_{K}}\)
现在我们可以得到一个结论:\(p_{1}^{c_{1}}+p_{2}^{c_{2}}+...+p_{K}^{c_{K}}\leq n\)
如果 \(p_{1}^{c_{1}}+p_{2}^{c_{2}}+...+p_{K}^{c_{K}} > n\) 那么就不合法
推到现在,我们就能得出一个DP
设为枚举到第 \(i\) 个质数,和为 \(j\) 的方案数
那我们就可以得出方程转移式
\[f_{i,j}=\sum_{k=1}^{k\leq j}f_{i-1,j-p_i^k}
\]
可以把二维滚成一维
\(Code\)
#include<cstdio>
#include<cstring>
using namespace std;
bool vis[2000];
long long tot,n,f[1500],b[1500];
void init()//筛N以内的素数
{
memset(vis,true,sizeof(vis));
tot=0;
for (int i=2;i<=n;i++)
{
if (vis[i]==true)
{
b[++tot]=i;
for (int j=i+i;j<=n;j+=i)
vis[j]=false;
}
}
}
int main()
{
scanf("%lld",&n);
init();
f[0]=1;
for (int i=1;i<=tot;i++)
{
for (int j=n;j>=1;j--)
{
int k=1;
while (k*b[i]<=j) f[j]+=f[j-b[i]*k],k*=b[i];
}
}
long long ans=0;
for (int i=1;i<=n;i++)
ans+=f[i];
printf("%lld\n",ans+1);
}

浙公网安备 33010602011771号