背包九讲(混合背包,分组背包)

文章目录

混合背包

简单来说就是多重背包与完全背包的混合,也就是说既存在可以无限获取的物品,也存在获取上限的物品

基本思想

这道题其实也就看着复杂,其实就是把三种背包问题放一起了。我们来分析一下,上面讲多重背包的时候,通过二进制优化,将多重背包分解为01背包来写,那么现在就变成了两种背包问题混合了,那么怎么处理呢?
可以将多重背包用二进制优化成01背包,然后再做一遍01背包与完全背包就行了

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int a[100100],b[100100],c[100100],v,w,s,m,n,cnt=0,f[100100];
int main()
{
    cin>>m>>n;
    for(int i=1;i<=m;i++)
    {
        cin>>v>>w>>s;
        if(s==0)
        {
            a[++cnt]=v;
            b[cnt]=w;
            c[cnt]=s;
        }
        else
        {
            if(s==-1)
            s=1;
            for(int j=1;j<=s;j*=2)
            {
                a[++cnt]=v*j;
                b[cnt]=w*j;
                c[cnt]=1;
                s-=j;
            }
            if(s>0)
            {
                a[++cnt]=v*s;
                b[cnt]=w*s;
                c[cnt]=1;
            }
        }
    }
    for(int i=1;i<=cnt;i++)
    {
        if(c[i])
        {
            for(int j=n;j>=a[i];j--)
            f[j]=max(f[j],f[j-a[i]]+b[i]);
        }
        else
        {
            for(int j=a[i];j<=n;j++)
            f[j]=max(f[j],f[j-a[i]]+b[i]);
        }
    }
    cout<<f[n]<<endl;
    return 0;
}

分组背包

问题描述

给定n nn个物品,以及一个容量大小为m mm的背包,然后给出n nn个物品的体积及价值,n个物品是分为若干组,每组最多只能选择一个物品。求背包最大价值是多少,也就是选择总体积不超过m mm的物品,然后使总价值最大。

基本思想


朴素代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int v[1010][1010],w[1010][1010],f[1010][1010],m,n,a,b,t[1010];
int main()
{
    cin>>m>>n;
    for(int i=1;i<=m;i++)
    {
        cin>>t[i];
        for(int j=1;j<=t[i];j++)
        {
            cin>>a>>b;
            v[i][j]=a,w[i][j]=b;
        }
    }
    for(int  i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
        {
            for(int k=0;k<=t[i];k++)
            {
                if(v[i][k]<=j)
                f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);
            }
        }
    }
    cout<<f[m][n]<<endl;
    return 0;
}

优化代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int v[1010][1010],w[1010][1010],f[1010],m,n,a,b,t[1010];
int main()
{
    cin>>m>>n;
    for(int i=1;i<=m;i++)
    {
        cin>>t[i];
        for(int j=1;j<=t[i];j++)
        {
            cin>>a>>b;
            v[i][j]=a,w[i][j]=b;
        }
    }
    for(int  i=1;i<=m;i++)
    {
        for(int j=n;j>=1;j--)
        {
            for(int k=0;k<=t[i];k++)
            {
                if(v[i][k]<=j)
                f[j]=max(f[j],f[j-v[i][k]]+w[i][k]);
            }
        }
    }
    cout<<f[n]<<endl;
    return 0;
}
相关推荐
ChoSeitaku几秒前
NO.79十六届蓝桥杯备战|数据结构-扩展域并查集-带权并查集|团伙|食物链|银河英雄传说(C++)
数据结构·c++·蓝桥杯
小羊在奋斗12 分钟前
【多源BFS】01 矩阵 / 飞地的数量 / 地图中的最高点 / 地图分析 / 腐烂的苹果
算法·矩阵·宽度优先
WG_1712 分钟前
图论:多源最短路
数据结构·c++·算法
一只小透明啊啊啊啊17 分钟前
【leetcode 100】贪心Java版本
java·算法·leetcode
白白糖1 小时前
组合与括号生成(回溯)
python·算法·力扣
whltaoin1 小时前
动态规划算法深度解析:0-1背包问题(含完整流程)
算法·动态规划
好好学习^按时吃饭1 小时前
蓝桥杯2022年第十三届省赛真题-统计子矩阵
算法·蓝桥杯
Swift社区2 小时前
LeetCode 249 解法揭秘:如何把“abc”和“bcd”分到一组?
算法·leetcode·职场和发展
大萌神Nagato2 小时前
Johnson算法 流水线问题 java实现
java·算法
爱coding的橙子2 小时前
蓝桥杯备赛 Day 20 树基础
数据结构·c++·算法·蓝桥杯·深度优先