01背包和dp入门
今天学了01背包,算是领略到dp的魅力了吧。。。>_<
开始还是有点难理解的,但是后面在草稿纸上画一画就懂了,花了半个多小时^^
第一种 01背包 1
题目大意:有一个背包体积为V,有N个物品,每个物品体积为Vi,取若干个物品放到背包里使背包剩余体积最小,每个物品只能放一次!!
输入:N,V,和N个整数表示每个物品体积
输出:一行,表示背包剩余的最小体积
其实就是要让背包里放的物品体积越大越好,我们建立可以定义个数组dp,大小是V+1,同时全部初始化为0,表示还没有放入物品
数组dp其实就是表示背包容量为0~V时可以装的物品体积的最优值
- 由于每个物品只能放一次,所以我们要倒序遍历
- 对于每一个物品,我们可以选择拿或者不拿
- 如果不拿,就是保持当前状态,也就是dp[j];如果拿,就是dp[j-items[i]]+items[i] (这里的items数组是用来存储每个物品的体积的)
- dp[j-items[i]]表示给新的物品items[i]腾出空间后,箱子原有的物品的体积和,那么现在要放入新的物品,则要加上这个物品的体积,也就是items[i]
由于题目说到我们需要让背包中物品的体积之和最大,就用头文件中的max函数比较一下就行了
于是我们得到状态方程:dp[j]=max(dp[j],dp[j-items[i]]+items[i])
一开始确实难理解!!但自己造一个简单样例,把过程全部写出来就能理解了!!!
现在我们可以得到一个完整的代码辣!!_
点击查看代码
#include<iostream>
#include<algorithm>
const int MAX_N=55;
const int MAX_V=1005;
int n,v;
int items[MAX_N];
int dp[MAX_V];
int main(){
cin>>n>>v;
for(int i=0;i<n;++i){
cin>>items[i];
}
for(int i=0;i<v;++i){
for(int j=v;j>=items[i];--j){//j>=items[i]是为了防止物品体积大于背包容量,倒序遍历是因为一个物品只能放一次
dp[j]=max(dp[j],dp[j-items[i]]+items[i]);//dp[j]表示:如果背包容量是j,最多能装多少体积的东西
//dp[j-物体体积]表示当箱子容量为dp[j-v]时,能装下的最大价值,这个值代表了“腾出v空间后,箱子原有物品的价值”。
}
}
cout<<v-dp[v]<<endl;
return 0;
}
第二种:01背包2
这个和上一种的唯一区别就是多了一个价值,每个物品有体积和价值,要求的就是让背包中物品价值最大
状态方程只有一个部分要变,就是把+items[i]改成+t[i](t数组表示每一个物品的价值)
点击查看代码
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX_N=55;
const int MAX_V=1005;
const int MAX_T=105;
int items[MAX_N],t[MAX_T],dp[1005];
int n,v;
int main(){
cin>>n>>v;
for(int i=0;i<n;++i){
cin>>items[i]>>t[i];
}
for(int i=0;i<n;++i){
for(int j=v;j>=items[i];--j){
dp[j]=max(dp[j],dp[j-items[i]]+t[i]);
}
}
cout<<dp[v]<<endl;//最多可以在背包里放多少价值的物品
return 0;
}
第三种:完全背包
就是第二种+每个物品可以放无限次。。。
我们只需要把倒序遍历改成正序遍历即可
点击查看代码
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX_N=55;
const int MAX_V=1005;
const int MAX_T=1005;
int items[MAX_N],t[MAX_T],dp[MAX_V];
int n,v;
int main(){
cin>>n>>v;
for(int i=0;i<n;++i){
cin>>items[i]>>t[i];
}
for(int i=0;i<n;++i){
for(int j=items[i];j<=v;++j){//因为一个物品可以拿多次,所以正序遍历
dp[j]=max(dp[j],dp[j-items[i]]+t[i]);
}
}
cout<<dp[v]<<endl;
return 0;
}
要赶紧去刷题了。。。。><
菜死了菜死了菜死了

浙公网安备 33010602011771号