题解 P4161 【[SCOI2009]游戏】

· · 题解

先无良宣传一下博客 wwwwww
文章列表 - 地灵殿 - 洛谷博客

知识点: 问题转化 , 背包DP

附代码:

#include<cstdio>
#include<ctype.h>
const int MARX = 1010;
//=============================================================
int n,num , prime[MARX];
bool vis[MARX];
long long ans,f[MARX]={1}; 
//=============================================================
inline int read() 
{
    int s=1, w=0; char ch=getchar();
    for(; !isdigit(ch);ch=getchar()) if(ch=='-') s =-1;
    for(; isdigit(ch);ch=getchar()) w = w*10+ch-'0';
    return s*w;
}
void get_prime()//埃氏筛筛出<=n的素数
{
    for(int i=2;i<=n;i++)
    {
      if(!vis[i]) prime[++num]=i;
      for(int j=1;i*j<=n;j++) vis[i*j]=1;
    } 
}
void dp()//完全背包 
{
    for(int i=1;i<=num;i++)//将每个质数拿出,作为物品 
      for(int k=n;k>=prime[i];k--)//枚举背包容量 
        for(int mul=prime[i];mul<=k;mul*=prime[i])//枚举 
          f[k]+=f[k-mul];
}
//=============================================================
signed main()
{
    n=read();
    get_prime();
    dp();
    for(int i=1;i<=n;i++) ans+=f[i];//获得各容量的方案数 
    printf("%lld",ans+1);//答案 = 总方案数 + 容量为0的方案 
}