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;
}

 

posted @ 2018-10-31 10:29  AKCqhzdy  阅读(101)  评论(0编辑  收藏