背包题的大特征:题目中某些参数(所有物品体积)相加<=一个不变的参数(背包体积)

题目(2019蓝桥国赛B题):2019可以被分解成若干个两两不同的素数,请问不同的分解方案有多少种?
注意:分解方案不考虑顺序,如2+2017=2019和2017+2=2019属于同一种方案。

背包题的大特征:题目中有一个参数不变,即背包(最大)体积不变,且要某些参数相加<=这个参数(体积)
先定(看是否符合)大特征,确定是背包题,再定(看是否符合)小特征,确定是哪种背包
装箱题:物品没有权值,只有体积,且体积相加是否等于某个固定值(即是否能装满某个空间)
01背包题:物品有权值,有体积
二维背包:题目中还有一个参数不变,即背包(最大)承重不变,且要某些参数相加<=这个参数(重量)。且物品有权值,有体积有重量
分组背包:同组物品互斥(每组物品最多只能拿一个)

先找出小于2019的所有素数
发现题目要我们拼凑素数,且和要为2019,
即题目有一个参数不变(2019),且素数相加要等于2019,所以为背包题
因为物品只有一个参数,且相加的体积要等于固定值(2019),所以是装箱题
求的是方案数即装满2019的方案数           转移方程:if(f[ j-v[i] ]) f[j]+=f[j-v[i]];
题目中的两两不同表示每个物品只能放一次

做题要会将题转化为某个模型

//

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int const N=5e3+7;
int n,m;
int z[N];   //欧拉筛的v[i],i的最小质因子 
int v[N];  //体积   //质数表 
ll f[N];
int main(){
    m=2019;
//以下是欧拉筛
    for(int i=2;i<=2019;++i){
        if(z[i]==0){
            z[i]=i;
            v[++n]=i;
        }
        for(int j=1;j<=n;++j){
            if( v[j]>z[i] || i*v[j]>2019 ) break;
            z[ i*v[j] ] = v[j];
        }
    }
//以下是装箱
    f[0]=1;
    for(int i=1;i<=n;++i){
        for(int j=m;j>=v[i];--j){
            if(f[j-v[i]]) f[j]+=f[j-v[i]];
        }
    }
    cout << f[m];
    return 0;
}
全部评论

相关推荐

Java大菜狗:纯纯招黑奴,一天还不到两百那么多要求,还不迟到早退,以为啥啊,给一点工资做一堆活,还以不拖欠员工工资为荣,这是什么值得骄傲的事情吗,纯纯***公司
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务