BUPT2017 wintertraining(15) #8F
1到n的排列,经过几次置换(也是一个排列)回到原来的排列,就是循环了。 现在给n(<=1000),求循环周期的所有可能数。
问题等价于几个正整数加起来等于n,求最小公倍数的可能数。 因为1不影响最小公倍数,所以等价于求几个正整数加起来小于等于n,最小公倍数的可能数。
最小公倍数与每个质因子在正整数里最大出现次数有关,所以枚举质因子的幂,进行dp。
dp[i][j]表示前i个质数,和为j时,最小公倍数的可能数。
dp[0][0]=1 转移就是
最后把dp[cnt][j]累加起来,答案就是dp[cnt][n]了。 可以写成一维的。
#include <cstdio> #define N 1001 typedef long long ll; ll dp[N]; bool com[N]; int cnt; int prime[N]; int main(){ for(int i=2;i<N;++i) if(!com[i]){ prime[++cnt]=i; for(int j=i+i;j<N;j+=i) com[j]=true; } dp[0]=1; for(int i=1;i<=cnt;++i) for(int j=N-1;j>=prime[i];--j) for(int k=prime[i];k<=j&&k<N;k*=prime[i]) dp[j]+=dp[j-k]; for(int i=1;i<N;++i) dp[i]+=dp[i-1]; int n; while(~scanf("%d",&n)) printf("%lld\n", dp[n]); return 0; }
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句