码迷,mamicode.com
首页 > 其他好文 > 详细

背包DP 方案数---P1832 A+B Problem(再升级)

时间:2019-12-02 19:36:32      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:lan   线性   cstring   int   include   数字   初始   素数   name   

P1832 A+B Problem(再升级)

题面描述

给定一个正整数n,求将其分解成若干个素数之和的方案总数。

题解

我们可以考虑背包DP实现

背包DP方案数板子题

f[ i ] = f[ i ] + f[ i - a[j] ] 

 

f[ j ] 表示数字 j 用若干个素数表示的方案总数

 

注意

1.线性筛不要写错:

  1)not_prime[maxn] maxn>=n

  2)memset not_prime 数组之后,0,1初始化不是素数

 2.方案数 DP 数组要开 long long

 

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<queue>

using namespace std;

typedef long long ll;

inline int read()
{
    int ans=0;
    char last= ,ch=getchar();
    while(ch<0||ch>9) last=ch,ch=getchar();
    while(ch>=0&&ch<=9) ans=ans*10+ch-0,ch=getchar();
    if(last==-) ans=-ans;
    return ans;
}

int n;
int prime[1000],not_prime[1050],cnt=0;
ll f[5000];

void xxs()
{
    memset(prime,0,sizeof(prime));
    memset(not_prime,0,sizeof(not_prime));
    not_prime[0]=not_prime[1]=1;
    for(int i=2;i<=n;i++){
        if(!not_prime[i]) prime[++cnt]=i;
        for(int j=1;j<=cnt;j++){
            if(i*prime[j]>n) break;
            not_prime[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}

int main()
{
    n=read();
    xxs();
    f[0]=1;
    for(int i=1;i<=cnt;i++)
      for(int j=prime[i];j<=n;j++)
         f[j]+=f[j-prime[i]];
    printf("%lld\n",f[n]);
    return 0;
}

 

背包DP 方案数---P1832 A+B Problem(再升级)

标签:lan   线性   cstring   int   include   数字   初始   素数   name   

原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11972112.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!