前情请见:
【动态规划】01背包问题 二维数组入门 详细讲解 | https://blog.csdn.net/m0_70400544/article/details/128818019?spm=1001.2014.3001.5502 |
【动态规划】01背包问题 一维数组空间优化 详细讲解 | https://blog.csdn.net/m0_70400544/article/details/128819799?spm=1001.2014.3001.5502 |
问题简介
完全背包问题非常类似于01背包问题,所不同的是每种物品有无限件,也就是从每种物品的角度考虑,与它相关的策略已并非取或不取两种,而是有取0件、取1件、取2件……取[c/]件等很多种。
题目描述
题目来源:http://ybt.ssoier.cn:8088/problem_show.php?pid=1268
做题思路
令k为物品的数量,看似k没有上限,但其实背包容量有限,k的范围是。
可以做出以下推算:
从而可以得出状态转移方程:
但是问题来了:二维数组空间会爆。如何滚动优化成一维数组呢?
其实这个二维数组的状态转移方程可以用与01背包问题一样的方法得出滚动优化的状态转移方程:dp[j]=max(dp[j],dp[j-w]+v),虽然与01背包问题一样,但是注意要正着循环。
正确代码
#include<bits/stdc++.h>
using namespace std;
int c,n,w,v,dp[100023];
/*
c : 背包容量
n : 物品数量
w : 当前物品的重量
v : 当前物品的价值
dp[背包容量]
*/
void solve(){
cin>>c>>n;
//遍历每个物品
for(int i=1;i<=n;i++){
cin>>w>>v;
//正着循环!!!
for(int j=w;j<=c;j++){
dp[j]=max(dp[j],dp[j-w]+v);
}
}
//输出答案
cout<<"max="<<dp[c];
}
int main(){
//加速输入输出
cin.tie(0);
ios::sync_with_stdio(0);
int tc=1; //cin>>tc;
while(tc--) solve();
return 0;
}
完全背包问题及一维数组空间优化