动态规划第二课——背包之01背包

来源:互联网 发布:网络随身听收音机 编辑:程序博客网 时间:2024/06/06 17:35

今天很高兴为大家讲动态规划第二课——背包,背包实际上有很多,01背包啊,完全背包啊,多重背包啊等等,今天这节我为大家讲解01背包,01背包实际上是背包问题中最简单的一个,什么是01背包呢?01背包就是假设一个背包,它的容量是W,现在有n个物品,每个物体有一个 重量w[i]和一个价值v[i](在后期的难题中可能还会有价格这种关键字),然后让在能装的情况,能获得的最大价值,由题意可知和第一节课一样,这种题不能用贪心,如果用贪心先按价值排序再装,最后可能有空位置装不了,也浪费了,这就要用到动态规划的思想了!马上看两道题!

载重
问题描述
轮船的最大载重为X(0≤v≤20000),同时有n(0≤n≤100)件货物,每件货物都有一个重量。要求从n件货物中,任取若千件装载。求该轮船的最小剩余载重量。
输入格式
第一行,一个整数,表示轮船的载重 第二行,一个整数,表示有n件货物 接下来N行,表示这N件物品的重量。
输出格式
一个整数,表示轮船最小剩余载重。
输入样例
24
6
8
3
12
7
9
7
输出样例
0

这道题是一个很明显的动态规划,但并不完全是01背包题,它没有w这个关键字,有二维的方法也有一维的,既然是第二堂课就先从简单的开始学,先把基础的学会,我们以后还会讲优化成一维的。

除了读入需要的数组,我们定义一个f数组,存放从1到第i个物品,装一个总容量为j的背包实际所能装的总重量,我知道这很难描述,可能这样说大家不太理解,没事,大家等一会看我代码里的注解

#include <bits/stdc++.h>using namespace std;int f[105][20005],a[105],n,s;int main(){    cin>>s>>n;    for (int i=1;i<=n;i++) cin>>a[i];    for (int j=1;j<=s;j++) if (j>a[1]) f[1][j]=a[1];//初始化第一个,不管背包的总容量为多大,只要a[1]能装的进去就装,因为就它一个    for (int i=2;i<=n;i++)        for (int j=1;j<=s;j++)        if (j>=a[i]) f[i][j]=max(f[i-1][j],f[i-1][j-a[i]]+a[i]);//如果能装的进去的话,有两种情况,前者为同第i-1的状态一样,意思就是说不取,后者是第i-1,j-a[i]状态加上当前的,意思是取        else f[i][j]=f[i-1][j];//如果装不下当然是不取了    cout<<s-f[n][s];//用背包总容量s减去从1到n,背包容量为s时能取得的最大值,就是结果}

大致的方法讲了,大家就可以试一试了,题目很多,基础的有开心的金明、最大约数和,只不过多加了一个关键字而已

原创粉丝点击