01背包问题

题目描述:

你是一名背包旅行者,准备出发去远足旅行。你有一个背包,其承重能力为 W。你还带着 n 个物品,每个物品的重量为 w[i],价值为 v[i]。每个物品只能选择放入背包或者不放入背包,即每个物品最多只能选择一次。这些物品的总价值和总重量是你需要考虑的因素。你希望在不超过背包承重能力的前提下,最大化背包中物品的总价值。

输入:

  • 第一行包含两个整数 W 和 n,分别表示背包的承重能力和物品的数量。
  • 接下来的 n 行,每行包含两个整数 w[i] 和 v[i],分别表示第 i 个物品的重量和价值。

输出:

  • 输出一个整数,表示在背包容量不超过 W 的情况下,物品的最大总价值。

示例:

输入:

5 4
1 1
2 2
3 3
4 4
 

输出:

1 2

说明:

在上述示例中,你可以选择放入重量为 1 和 2 的两个物品,这样背包中的总重量是 3,总价值是 1 + 2 = 3。

程序:

#include<bits/stdc++.h>
using namespace std;
int a[1001][3],dp[1001][10001]; 
int main(){
	int w,n;
	cin>>w>>n;
	for(int i=0;i<n;i++){
		cin>>a[i][0]>>a[i][1]>>a[i][2];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=w;j++){
			if(j<a[i][0]){
				dp[i][j]=dp[i-1][j];
			}
			else
				dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i][0]]+a[i][1]);
		}
	}
	int k=w;
	for(int i=n;i>=1;i--){
		if(dp[i][k]!=dp[i-1][k]){
			cout<<i<<" ";
			k=k-a[i][0];
		}
	}
	return 0;
} 

这个程序是用来解决“01背包问题”的,具体来说,它实现了一个动态规划算法来找出在给定的背包容量和物品的情况下,能够获得的最大价值,并且还输出了最优解中选择的物品编号。下面是对程序的逐行解读:

1. 头文件和全局变量声明

#include<bits/stdc++.h>
using namespace std;
int a[1001][3], dp[1001][10001];
  • #include<bits/stdc++.h>:包含了所有标准库头文件,简化代码书写。
  • a[1001][3]:用于存储每个物品的属性。a[i][0]表示物品的重量,a[i][1]表示物品的价值,a[i][2](未用到)可能是用于其他信息。
  • dp[1001][10001]:用于存储动态规划的状态,dp[i][j]表示在前 i 个物品中,背包容量为 j 时能获得的最大价值。

2. 主函数

int main() {
    int w, n;
    cin >> w >> n;
  • w:背包的最大容量。
  • n:物品的数量。
    for (int i = 0; i < n; i++) {
        cin >> a[i][0] >> a[i][1];
    }
  • 输入每个物品的重量和价值。
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= w; j++) {
            if (j < a[i-1][0]) {
                dp[i][j] = dp[i-1][j];
            } else {
                dp[i][j] = max(dp[i-1][j], dp[i-1][j-a[i-1][0]] + a[i-1][1]);
            }
        }
    }
  • 使用动态规划来填充 dp 表。dp[i][j] 的值是通过考虑是否包含第 i 个物品来更新的。
    • 如果当前背包容量 j 小于物品 i 的重量,则不能放入这个物品,只能继承前一个状态 dp[i-1][j]
    • 否则,选择最大值:不放入这个物品的价值 dp[i-1][j] 和放入这个物品的价值 dp[i-1][j-a[i-1][0]] + a[i-1][1]
    int k = w;
    for (int i = n; i >= 1; i--) {
        if (dp[i][k] != dp[i-1][k]) {
            cout << i << " ";
            k = k - a[i-1][0];
        }
    }
    return 0;
}
  • 从 dp 表中反向追踪选择的物品。根据 dp 表中状态的变化来确定哪些物品被选中。如果 dp[i][k] 与 dp[i-1][k] 不同,则说明第 i 个物品被选中。
    • 打印出被选中的物品编号,并更新背包容量 k,减少相应物品的重量。

总结

这个程序通过动态规划解决了01背包问题,并输出了在给定背包容量下能够获得的最大价值和选择的物品编号。程序利用二维 dp 数组来存储子问题的解,并最终从 dp 数组中反向追踪出最终的解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值