根据置换的知识,易得题目等价于:
给定n,将n“拆”成数列{ai}满足Q=lcm(ai)且Σai≤n,求有多少种可能的Q,其中lcm(ai)表示数列中所有数的最小公倍数.
根据观察,又易得:
lcm(ai)=Q(Q为定值)时,当ai形如pkii(p为质数)时,Σai最小.
所以我们只需要把n“拆”成“ai形如pkii(p为质数)的数列{ai}”,即可取遍所有可能的Q.
然后易得题目等价于:
Q=Πpkii,其中pi为第i小的质数,Σpkii≤n,求所有可能的Q的个数.
然后题目就简单了,DP即可.
AC code:
#include <cstdio>
typedef long long ll;
const int N=1010;
ll n,tot,ans;
ll prm[N];
ll f[N][N];
bool flag[N];
int main(){
scanf("%lld",&n);
for(ll i=2;i<=n;i++){
if(!flag[i]) prm[++tot]=i;
for(ll j=1;j<=tot&&i*prm[j]<=n;j++){
flag[i*prm[j]]=1;
if(!(i%prm[j])) break;
}
}
f[0][0]=1;
for(ll i=1;i<=tot;i++){
for(ll j=0;j<=n;j++){
f[i][j]=f[i-1][j];
for(ll k=prm[i];j-k>=0;k*=prm[i])f[i][j]+=f[i-1][j-k];
}
}
for(ll i=0;i<=n;i++) ans+=f[tot][i];
printf("%lld\n",ans);
return 0;
}