Acwing_3. 完全背包问题

原题链接:

3. 完全背包问题 - AcWing题库

二维:

题解:

相比于之前的01背包问题,完全背包的每种物品都有无限件可用。

分为2种情况:选和不选

不选的情况和之前的相同,都是f[i-1][j]

选的情况中,就需要考虑选当前物品多少个,列出如下公式。

可以发现紫框部分=绿框部分+w,因此进行替换得到:

f[i,j] = max(f[i-1,j],f[i,j-v]+w)

代码:
#include<bits/stdc++.h>
using namespace std;
int n, V;
const int N = 1e3 + 10;
int v[N], w[N];
int f[N][N];//f[i][j]表示考虑前i个物品,在背包容量为j的前提下的最优解

int main() {
	cin >> n >> V;
	for (int i = 1;i <= n;i++) cin >> v[i] >> w[i];
	for (int i = 1;i <= n;i++) {
		for (int j = 0;j <= V;j++) {
			f[i][j] = f[i - 1][j];//不选第i个物品
			if (v[i] <= j) f[i][j] = max(f[i][j], f[i][j - v[i]] + w[i]);//选择第i个物品
		}
	}
	cout << f[n][V];
}

一维:

题解:

和01背包同理,对二维进行等价化转换为一维。

但是因为更新公式进行了调整,从:

f[i,j] = max(f[i-1,j],f[i-1,j-v]+w)

调整为:

f[i,j] = max(f[i-1,j],f[i,j-v]+w) 

因此我们需要将01背包中容量的遍历顺序改为顺序,这是因为f[i][j-v]代表更新的时候要依赖于当前轮的状态。 

代码:
#include<bits/stdc++.h>
using namespace std;
int n, V;
const int N = 1e3 + 10;
int v[N], w[N];
int f[N];//f[j]表示在背包容量为j的前提下的最优解

int main() {
	cin >> n >> V;
	for (int i = 1;i <= n;i++) cin >> v[i] >> w[i];
	for (int i = 1;i <= n;i++) {
		for (int j = v[i];j <= V;j++) {
			f[j] = max(f[j], f[j - v[i]] + w[i]);
		}
	}
	cout << f[V];
}
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值