上期给大家讲了分组背包问题的二维数组解法,没看过的建议先去看看。
分组背包问题之二维数组
另外分组背包其实就是由01背包转化而来的,不知道01背包怎么做的建议先去学学,也可以看看我的文章。
01背包问题之一维数组
上篇文章结尾也说了,分组背包问题可以用一维数组解决,这次就来解决它。
题目如下:
【题目介绍】
有 N 组物品和一个容量是 V 的背包。
每组物品有若干个,同一组内的物品最多只能选一个。
每件物品的体积是 vij,价值是 wij,其中 i 是组号,j 是组内编号。
求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。
输出最大价值。
【输入格式】
第一行有两个整数 N,V,用空格隔开,分别表示物品组数和背包容量。
接下来有 N 组数据:
每组数据第一行有一个整数 Si,表示第 i 个物品组的物品数量;
每组数据接下来有 Si 行,每行有两个整数 vij,wij,用空格隔开,分别表示第 i 个物品组的第 j 个物品的体积和价值;
【输出格式】
输出一个整数,表示最大价值。
【数据范围】
0<N,V≤100
0<Si≤100
0<vij,wij≤100
【输入样例】
3 5
2
1 2
2 4
1
3 4
1
4 5
【输出样例】
8
原题链接:原题链接
还是一样,【算法分析】和【数据存储】这里就不再啰嗦说一遍了,感兴趣的自己去看看。
【dp数组含义】
还是和01背包一维数组的dp数组含义一样,就是背包容量为 j 的背包能装的最大价值。
【填表】
填表其实和二维的分组背包差不了太多,只要将所有的二维dp数组降为一维dp数组即可,即:
for(int i=1;i<=n;i++){
//循环物品
for(int j=m;j>=0;j--){
//循环背包,由于是由01背包转变而来,所以依然要倒序循环
dp[j]=dp[j];
for(int k=0;k<s[i];k++){
//循环第 i 个物品组的每个物品
递推公式
}
}
}
由上面我们可以发现,dp[j]=dp[j]这不是句废话吗,所以可以将其删掉。
【递推公式】
既然填表时降了一维,那其实递推公式再降一维即可了,即:
if(v[i][k]<=j)dp[j]=max(dp[j],dp[j-v[i][k]]+w[i][k]);
【初始化】
所有背包问题的一维数组解法都是一样的