0/1背包问题

问题描述:给定N个物品,每个物品有一个重量W和一个价值V.你有一个能装C重量的背包.问怎么装使得所装价值最大.每个物品只有一个.

参考文档:https://blog.csdn.net/liuxiao214/article/details/78565707 

 

1. 数组长度==物品数量+1

#include <iostream>  
#include <cstdio>
#include <cstdlib>
#include <thread> 
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <stack>
#include <typeinfo>
#include <algorithm>
#include <sstream>
#include <functional>
#include <iterator>
using namespace std;


int main(void)
{
	const int N = 5; //物体数目
	
	//注意val和wei长度为6.要在下标为0处加入一个数,否则后面数组越界
	vector<int> val{0, 6, 3, 5, 4, 6 }; //物体价值
	vector<int> wei{0, 2, 2, 6, 5, 4 }; //物体重量
	const int cap = 10; //背包容量

	//dp共(N+1)行,(cap+1)列
	//dp[0][j] = 0,这个意思是说,当没有物品放入时,不管背包容量多少,其最大价值为0;
	//dp[i][0] = 0,当背包容量为空时,不管从前i件物品中怎么取,最大价值也还是0。
	//dp[i][j]表示物品1~i,在重量不超过j的情况下可以达到的最大价值
	vector<vector<int>> dp(N+1, vector<int>(cap+1, 0)); 
	//此时已初始化边界条件,dp(0, j) = dp(i, 0) = 0

	for (int i = 1; i <= N; i++)
	{
		for (int j = 1; j <= cap; j++)
		{
			if (wei[i] > j) //第i个物体放不进去
				dp[i][j] = dp[i - 1][j];
			else //第i个物体可以放进去,取以下两种情况较大者:1.不放i物体 2.放置i物体
				dp[i][j] = std::max(dp[i-1][j], dp[i-1][j-wei[i]] + val[i]);
		}
	}



	for (int i = 1; i <= N; i++)
	{
		for (int j = 1; j <= cap; j++)
			printf("dp[%d][%d] = %d\t", i, j, dp[i][j]);
		cout << endl;
	}

	return 0;
}

 2.数组长度==物品数量

#include <iostream>  
#include <cstdio>
#include <cstdlib>
#include <thread> 
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <stack>
#include <typeinfo>
#include <algorithm>
#include <sstream>
#include <functional>
#include <iterator>
using namespace std;


int main(void)
{
	const int N = 5; //物体数目
	
	vector<int> val{6, 3, 5, 4, 6 }; //物体价值
	vector<int> wei{2, 2, 6, 5, 4 }; //物体重量
	const int cap = 10; //背包容量

	//dp共N行,(cap+1)列
	//dp[i][0] = 0,当背包容量为空时,不管从前i件物品中怎么取,最大价值也还是0。
	//dp[i][j]表示物品0~i,在重量不超过j的情况下可以达到的最大价值
	vector<vector<int>> dp(N, vector<int>(cap+1, 0)); 
	//此时已初始化边界条件,第一列dp(i, 0) = 0
	//下面初始化第一行
	for (int j = 0; j <= cap; j++)
	{
		if (j >= wei[0]) 
			dp[0][j] = val[0];
	}

	for (int i = 1; i < N; i++)
	{
		for (int j = 1; j <= cap; j++)
		{
			if (wei[i] > j) //第i个物体放不进去
				dp[i][j] = dp[i - 1][j];
			else //第i个物体可以放进去,取以下两种情况较大者:1.不放i物体 2.放置i物体
				dp[i][j] = std::max(dp[i-1][j], dp[i-1][j-wei[i]] + val[i]);
		}
	}



	for (int i = 0; i < N; i++)
	{
		for (int j = 1; j <= cap; j++)
			printf("dp[%d][%d] = %d\t", i, j, dp[i][j]);
		cout << endl;
	}

	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值