分组背包问题笔记
2023-12-16 17:45:46
分组背包是选不同的组,每个组中只能选一个物品。分组背包就是01背包的变种,多重背包就是特殊的分组背包。
//分组背包
#include<iostream>
using namespace std;
const int N = 110;
int f[N], v[N], w[N], n, m;
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 0; i < n; ++i)
{
int s; cin >> s;
//初始化每组的数据
for (int j = 0; j < s; ++j) cin >> v[j] >> w[j];
for (int j = m; j >= 0; --j)
{
for (int k = 0; k < s; ++k)
{
//这里必须加上判断,因为这里j没有做限制
if (j - v[k] >= 0) f[j] = max(f[j], f[j - v[k]] + w[k]);
}
}
}
cout << f[m];
return 0;
}
?还有一种方法优化空间:就是将物品放在外层循环:
#include <bits/stdc++.h>
using namespace std;
const int M = 110;
int dp[M], last[M];
int N, V, S, v, w;
int main()
{
cin >> N >> V;
for (int i = 0; i < N; i++)
{
cin >> S;
for (int j = 0; j < S; j++)
{
cin >> v >> w;
for (int k = V; k >= v; k--)
dp[k] = max(dp[k], last[k - v] + w);
}
memcpy(last, dp, sizeof dp);
}
cout << dp[V] << endl;
return 0;
}
每次last数组保存上一次的状态,每个物品都会更新一次f[0]到f[V],如果不记录上一次的状态,不需要加上if条件(循环k中已经加了限制了),就必须写成二维的数组了。这时就需要加上if条件了。优化掉的空间就是开数组的空间。
for(int i=1;i<=n;i++){
int s;
scanf("%d",&s);
for(int k=1;k<=s;k++){//第i组第k个物品
int a,b;
scanf("%d%d",&a,&b);
for(int j=v;j>=0;j--){
f[i][j]=max(f[i][j],f[i-1][j]);
if(j>=a) f[i][j]=max(f[i][j],f[i-1][j-a]+b);
}
}
}
一维数组无法取得上一层的状态 。
?
?
文章来源:https://blog.csdn.net/qq_73185160/article/details/135034577
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!