读完题我们可以分成两部分。
第一部分是把n拆成由数字1~n组成的不同排列。
如3=1+1+1
3=2+1
3=3
第二部分是:排列中每个数的最小公倍数。
每个排列的最小公倍数去重后的个数是答案。
对于第二部分,我们想一想,可以发现,最小公倍数可以分为多个质因数。
所以对于第一部分,我们要用n以下的质数组成n的排列。
将两部分结合起来就是用n以下的素数的无限背包。

#include<cstdio>
#include<cstring>
#define ll long long
const int M=1010;
ll f[M];//f[j]为和为j的不同排数 
int n,len=0;

int p[M],v[M];

void prim()
{
    memset(v,0,sizeof(v));
    for(int i=2;i<=M;i++)
    {
        if(v[i]==0)v[i]=i,p[++len]=i;
        for(int j=1;j<=len && p[j]<=v[i] &&(p[j]*i<=M);j++)
        v[i*p[j]]=p[j];
    }
}

int main()
{
    scanf("%d",&n);
    prim();
    memset(f,0,sizeof(f));
    f[0]=1ll;
    for(int i=1;i<=len&&p[i]<=n;i++)
    {
        for(int j=n;j>=p[i];j--)
        {
            int x=p[i];//printf("%d\n",p[i]);
            while(x<=j)f[j]+=f[j-x],x*=p[i];//防止重复计算
        }
    }
    ll ans=1ll;
    for(int i=1;i<=n;i++)ans+=f[i];
    printf("%lld",ans);
    return 0;
}