这道题题目很长,废话太多。
说白了就是有若干个正整数,它们的和为
n
,求
把题目看透后,似乎题变简单了。然后一眼就看出是一个DP。
然而蒟蒻还是不会做。动规弱爆了= =
决定最小公倍数的,是这些数的质因数以及对应的幂。
那么首先筛一下素数吧,然后DP。
/**************************************************************
Problem: 1025
Time:20 ms
Memory:9168 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#define MAXN 1005
#define LL long long int
using namespace std;
bool flag[MAXN];
int n, prime[MAXN], cnt;
LL f[MAXN][MAXN];
void table(int n)
{
for(int i=2;i<=n;++i)
{
if(!flag[i])prime[++cnt]=i;
for(int j=1;j<=cnt;++j)
{
if(i*prime[j]>n)break;
flag[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
int main()
{
scanf("%d",&n);
table(n);
f[0][0]=1;
//f[i][j]表示前i个素数的和为j时最小公倍数的个数(当然有一些数木有用)。由于是枚举素数,不存在最小公倍数重复的情况
for(int i=1;i<=cnt;++i)
{
for(int j=0;j<=n;++j)
f[i][j]=f[i-1][j];
for(int k=prime[i];k<=n;k*=prime[i])
for(int j=0;j+prime[i]<=n;++j)
f[i][j+k]+=f[i-1][j];
}
LL ans=0;
//注意:若和没有到达n,就用1来补。
for(int i=0;i<=n;++i)
ans+=f[cnt][i];
printf("%lld\n",ans);
return 0;
}