01背包问题及二维费用背包问题(一)

简介: 01背包问题及二维费用背包问题

前言

AcWing算法提高课内容,本文讲解 动态规划

本篇包括以下题目:

⭐️ AcWing 423. 采药

⭐️ AcWing 1024. 装箱问题

⭐️ AcWing 278. 数字组合

⭐️ AcWing 8. 二维费用的背包问题

⭐️ AcWing 1020. 潜水员

⭐️ AcWing 1022. 宠物小精灵之收服


写博客有哪里不完善的地方或者有哪里表达错误希望大家提出来,博主会立即改正!望大家海涵


本文需要先自修基础:背包问题

注:本文中的所有代码全部为优化后的代码,且不提供优化解释,解释请见:背包问题,其中有详细的解释


AcWing 423. 采药

题目要求

题目描述:

辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。

为此,他想拜附近最有威望的医师为师。

医师为了判断他的资质,给他出了一个难题。

医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

输入格式:

输入文件的第一行有两个整数 T 和 M ,用一个空格隔开,T  代表总共能够用来采药的时间,M 代表山洞里的草药的数目。

接下来的 M  行每行包括两个在 1 到 100 之间(包括 1 和 100 )的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出格式:

输出文件包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

数据范围:

1T1000,

1M100

输入样例:

70 3
71 100
69 1
1 2

输出样例:

3

思路分析

01背包的裸题,f [ i ]表示总时间不超过 i 的情况下可以采到的草药最大价值,可以说就是把01背包中的体积和质量变换为了时间和草药价值,直接把模板改改数据范围扔上来即可。

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int f[N];
int main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= m; i ++ )
    {
        int v, w;
        cin >> v >> w;
        for (int j = n; j >= v; j -- )
            f[j] = max(f[j], f[j - v] + w);
    }
    cout << f[n] << endl;
    return 0;
}

AcWing 1024. 装箱问题

题目要求

题目描述:

有一个箱子容量为 V ,同时有 n 个物品,每个物品有一个体积(正整数)。

要求 n 个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

输入格式:

第一行是一个整数 V ,表示箱子容量。

第二行是一个整数 n ,表示物品数。

接下来 n  行,每行一个正整数(不超过10000 ),分别表示这 n 个物品的各自体积。

输出格式:

一个整数,表示箱子剩余空间。

数据范围:

0<V20000,

0<n30

输入样例:

24
6
8
3
12
7
9
7

输出样例:

0

思路分析

也是一道01背包的裸题,与模板不同的是,这里的体积即为模板中的体积也为模板中的价值,且需要注意题目问的是剩余空间,故需要用总空间去减去用掉的空间,f[i]表示的是在总体积不超过 i ii 的情况下箱子内的最大体积。

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 20010;
int f[N];
int main()
{
    int V, n;
    cin >> V >> n;
    for (int i = 1; i <= n; i ++ )
    {
        int v;
        cin >> v;
        for (int j = V; j >= v; j -- )
            f[j] = max(f[j], f[j - v] + v);
    }
    cout << V - f[V] << endl;
    return 0;
}

AcWing 278. 数字组合

题目要求

题目描述:

给定 N 个正整数A1,A2,,AN从中选出若干个数,使它们的和为 M ,求有多少种选择方案。

输入格式:

第一行包含两个整数 N 和 M 。

第二行包含 N 个整数,表示A1,A2,,AN。

输出格式:

包含一个整数,表示可选方案数。

数据范围:

1N100,

1M10000,

1Ai1000,

答案保证在 i n t 范围内。

输入样例:

4 4
1 1 2 2

输出样例:

3

思路分析

注意到前两题都是求的最大价值,本题和前两题的唯一区别就是求的是方案数,求最大我们不需要对 f 数组进行初始化操作,因为 f数组内的元素默认是0,0就是最小的情况了,求决策数和最小价值的时候,就需要对我们的 f 数组的部分元素做修改,我们本题规定 f [ i ] 表示选出的数的和正好为 i的情况下的决策数,所以我们的 f [ 0 ]应该初始化为 1 ,代表的是和为 0 的情况下,有一种方法:即全部都不选,因为求的是决策数,故状态转移方程就不再是:f[j] = max(f[j], f[j - v] + w);,而应该改为:f[j] += f[j - a];

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010;
int f[N];
int main()
{
    int n, m;
    cin >> n >> m;
    f[0] = 1;
    for (int i = 1; i <= n; i ++ )
    {
        int a;
        cin >> a;
        for (int j = m; j >= a; j -- )
            f[j] += f[j - a];
    }
    cout << f[m] << endl;
    return 0;
}




目录
相关文章
|
5月前
|
存储 JavaScript 算法
【背包问题】01背包问题和完全背包问题的模板
【背包问题】01背包问题和完全背包问题的模板
|
6月前
【模板】完全背包和01背包
【模板】完全背包和01背包
37 1
|
6月前
01背包和完全背包
01背包和完全背包
|
6月前
|
算法
算法系列--动态规划--背包问题(5)--二维费用背包问题(下)
算法系列--动态规划--背包问题(5)--二维费用背包问题(下)
40 0
|
6月前
|
算法
算法系列--动态规划--背包问题(5)--二维费用背包问题(上)
算法系列--动态规划--背包问题(5)--二维费用背包问题(上)
57 0
|
人工智能 算法 决策智能
动态规划之背包问题(01背包问题、完全背包问题、方案数填满型背包问题)
动态规划之背包问题(01背包问题、完全背包问题、方案数填满型背包问题)
248 1
|
算法 决策智能
背包问题——01背包|完全背包 1
背包问题——01背包|完全背包
312 0
背包问题——01背包|完全背包 2
背包问题——01背包|完全背包
187 0
|
测试技术 容器
动态规划之背包问题——背包三讲(01背包,完全背包,多重背包)(三)
动态规划之背包问题——背包三讲(01背包,完全背包,多重背包)(三)
212 0
动态规划之背包问题——背包三讲(01背包,完全背包,多重背包)(三)