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

Posted xiaoyezi-wink

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了背包DP 方案数---P1832 A+B Problem(再升级)相关的知识,希望对你有一定的参考价值。

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
",f[n]);
    return 0;
}

 

以上是关于背包DP 方案数---P1832 A+B Problem(再升级)的主要内容,如果未能解决你的问题,请参考以下文章

[luoguP1417] 烹调方案(背包DP)

[ZJOI2019]开关(生成函数+背包DP)

HDU 5119 Happy Matt Friends ——(背包DP)

A+B Problem(再升级)

背包DP || Codeforces 544C Writing Code

洛谷 P1064 金明的预算方案DP/01背包-方案数