1. 程式人生 > 其它 >#01揹包#洛谷 4161 [SCOI2009]遊戲

#01揹包#洛谷 4161 [SCOI2009]遊戲

01揹包

題目

\(n\) 拆成若干個正整數的和,
問這些正整數的LCM有多少種
\(n\leq 10^3\)


分析

考慮這個\(LCM\)一定是1或者由若干個質數的指數冪相乘得到的,
那麼可以設\(dp[i]\)表示選擇質數或其指數冪的和為\(i\)的方案數,
直接01揹包即可,答案為\(\sum_{i=0}^ndp[i]\)


程式碼

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=1011;
long long dp[N];
int v[N],prime[N],n,Cnt;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
signed main(){
	n=iut();
	for (rr int i=2;i<=n;++i)
	if (!v[i]){
		prime[++Cnt]=i;
		for (rr int j=i+i;j<=n;j+=i)
		    v[j]=1;
	}
	dp[0]=1;
	for (rr int i=1;i<=Cnt;++i)
	for (rr int j=n;j>=prime[i];--j){
		rr int p=prime[i];
		for (;j>=p;p*=prime[i]) 
		    dp[j]+=dp[j-p];
	}
	for (rr int i=1;i<=n;++i) dp[0]+=dp[i];
	return !printf("%lld",dp[0]);
}