标签:根据 c++ 置换 练习题 ++ class printf dash 影响
这是一道置换练习题,学过置换就是一道较简单的DP题;
首先,观察到题目中要求的操作其实就是置换,让求置换多少次变回去;
根据置换的知识点(或直觉)得出结论——层数等于置换中各个循环的长度的LCM;
又可以转化成把n个元素分成m个集合,让你求各集合大小的LCM的情况数;
由于LCM与质数的关系,不难想到只考虑集合大小为质数的k次幂的情况;
又观察到质数与质数之间互不影响,于是想到用DP;
于是f(i,j)表示出现了前个i质数的次幂的大小的集合,用了j个元素的情况数;
代码如下:
#include<bits/stdc++.h> using namespace std; long long n,zs[1010],t,dp[1010]; bool isss[1010]; int main() { scanf("%lld",&n); for(long long i=2;i<=n;i++) { if(!isss[i]) zs[++t]=i; for(long long j=1;j<=t;j++) { long long tmp=i*zs[j]; if(tmp>n) break; isss[tmp]=1; if(i%zs[j]==0) break; } } dp[0]=1; for(long long i=1;i<=t;i++) for(long long j=n;j>=zs[i];j--) { long long tmp=zs[i]; while(tmp<=j) { dp[j]+=dp[j-tmp]; tmp*=zs[i]; } } for(long long i=1;i<=n;i++) dp[i]+=dp[i-1]; printf("%lld",dp[n]); }
标签:根据 c++ 置换 练习题 ++ class printf dash 影响
原文地址:https://www.cnblogs.com/Cduiz/p/12256419.html