bzoj1025: [SCOI2009]游戏
之前模拟赛好像出过,然而我只会信仰打表找规律
现在再看的的话,容易把问题转换成把n拆成多个数,不同的最小公倍数个数
然而搞出来我还是不是很会,发现自己分组背包没学好。。。
素数对于最小公倍数的贡献是要取要么不取的区别,而对于空间的占用多次取是关于指数的
那么可以把p,p^2,p^3……p^q看成一组背包
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; int pr,prime[2100]; bool v[2100]; void get_prime() { pr=0; for(int i=2;i<=2000;i++) { if(v[i]==false)prime[++pr]=i; for(int j=1;j<=pr&&i*prime[j]<=2000;j++) { v[i*prime[j]]=true; if(i%prime[j]==0)break; } } } LL f[210][1100]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); get_prime(); int n,i; scanf("%d",&n); f[0][0]=1; for(i=1;prime[i]<=n;i++) for(int j=0;j<=n;j++) { f[i][j]=f[i-1][j]; for(int k=prime[i];k<=j;k*=prime[i]) f[i][j]+=f[i-1][j-k]; } LL ans=0; for(int j=0;j<=n;j++)ans+=f[i-1][j]; printf("%lld\n",ans); return 0; }
pain and happy in the cruel world.