背包问题求方案数

有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。

第 i 件物品的体积是 vi,价值是 wi。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输出 最优选法的方案数。注意答案可能很大,请输出答案模 109+7 的结果。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式

输出一个整数,表示 方案数 模 109+7 的结果。

数据范围

0<N,V≤1000
0<vi,wi≤1000

输入样例

4 5
1 2
2 4
3 4
4 6

输出样例:

2

 思路:在用f[i]记录体积为i时的最大价值时,新开一个数组num[i]记录体积为i时的方案数,因为每个物品只装一次,所以这是一个01背包问题,遍历体积时仍需从大到小逆序遍历,但最后求的时体积恰好为m时的最大方案数,所以这里初始化时f[j]数组除了0号位置,其他位置均初始化为-inf,因为这样才能表示体积恰好为j时的最大价值,即:体积为0也就是什么也不装时(恰好体积为0,“恰好装满”),为合法状态,此时最大价值为0,其他体积状态均不是“恰好装满”,是非法状态,不能选,所以赋值为-inf,保证在取max时取不到该非法状态。(01背包初始化细节参考https://blog.csdn.net/qq_42804678/article/details/81662367对于num[]数组,初始化时,num[0]=1,表示体积为0的方案数为1,其他状态均有此递推过来,最后找到最大价值,遍历num[]数组,统计等于最大价值时的所有体积下的方案数之和sum即为答案。

完整代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1010;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
int f[maxn],num[maxn];

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++) f[i]=-inf;
    num[0]=1;
    for(int i=0;i<n;i++){
        int v,w;
        cin>>v>>w;
        for(int j=m;j>=v;j--){
            int t=max(f[j],f[j-v]+w);
            int s=0;
            if(t==f[j]) s+=num[j];//s统计当前最大价值对应体积下的方案数之和
            if(t==f[j-v]+w) s+=num[j-v];
            if(s>mod) s-=mod;
            f[j]=t;
            num[j]=s;
        }
    }
    int ans=0;
    for(int i=0;i<=m;i++){
        ans=max(ans,f[i]);
    }
    int sum=0;
    for(int i=0;i<=m;i++){
        if(f[i]==ans){
            sum+=num[i];
            if(sum>mod)
                sum-=mod;
        }
    }
    cout<<sum<<endl;
    return 0;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
粒子群优化算法(Particle Swarm Optimization,PSO)可以用来背包问题背包问题是一个经典的组合优化问题,其中给定一组物品,每个物品有一个重量和一个价值,目标是选择一些物品放入背包中,使得放入背包的物品总重量不超过背包的容量,且总价值最大化。 下面是使用粒子群算法背包问题的一般步骤: 1. 初始化粒子群:随机生成一组粒子,每个粒子代表一个解,即一组物品的选择方案。 2. 更新粒子的速度和位置:根据当前的位置和速度,通过公式计算新的速度和位置。速度决定了粒子在搜索空间中移动的方向和速率。 3. 评估适应度:对于每个粒子,计算其对应的解在背包问题中的适应度。适应度函通常根据背包问题的约束条件和目标函定义。 4. 更新个体最优解:对于每个粒子,比较其当前位置下的适应度与个体历史最优解的适应度,并更新个体最优解。 5. 更新全局最优解:从所有粒子的个体历史最优解中选择适应度最好的解作为全局最优解。 6. 终止条件判断:根据预设的终止条件(例如达到最大迭代次或找到满意解),判断是否结束算法。 7. 迭代更新:如果未达到终止条件,则返回步骤2,迭代更新粒子的速度和位置。 在每次迭代过程中,粒子的速度和位置的更新是通过考虑个体历史最优解和全局最优解而进行的。这样,粒子群会通过信息共享和合作,在搜索空间中逐渐寻找到最佳解。 需要注意的是,具体实现时需要根据背包问题的具体约束和目标函进行适当的调整和定义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值