努力变小神


私信TA

用户名:dotcpp0645728

访问量:1083

签 名:

等  级
排  名 12565
经  验 965
参赛次数 0
文章发表 4
年  龄 0
在职情况 学生
学  校 南京信息工程大学
专  业

  自我简介:

TA的其他文章

解题思路:

01背包问题也就是每样物品有放和不放两种选择的问题。题目要解决的问题是如何组合放入背包的物品来达到价值最大化。

假设共有3件物品,分别选择放、放,不放。那么解可以抽象为(110);

当然,只有3件物品的话,有2*2*2种不同的组合。

即解空间里包含了8种组合。可以采用递归遍历解空间计算的方法解决问题。

注意事项:
如果不进行优化剪枝的话(优化剪枝:每次进入递归函数后时对当前背包里面体积进行判断,如果大于,则不用考虑后续情况。)数据量大的测试样例会超时。
参考代码:

#include<iostream>
#include<vector>
using namespace std;

#define x first
#define y second
#define pll pair<int,int>

vector<pll>s;
vector<int>pack;
int m;//最大价值
int V;//总体积
int counter;
int cnt_print;

int sum_price()
{
	int sum = 0;
	for (int i = 0; i < pack.size(); ++i)
	{
		if (pack[i] != 0)
			sum += s[i - 1].y;
	}
	return sum;
}

int sum_v()
{
	int sum = 0;
	for (int i = 1; i < pack.size(); ++i)
	{
		if (pack[i] != 0)
			sum += s[i - 1].x;
	}
	return sum;
}

void B(int i, int k)
{
	if (i > s.size())
	{
		/*for (int i = 1; i < pack.size(); ++i)
			cout << pack[i];
		cout << endl;*/
		return;
	}//是否走完

	pack[i] = k;

	if (sum_v() > V)
		return;
	//counter++;

	
	if (sum_price() > m && sum_v() <= V)
		m = sum_price();

	
	B(i + 1, 1);

	if (i + 1 > s.size())
		return;
	B(i + 1, 0);

}


int main()
{
	int n = 0;
	int x1 = 0;
	int y1 = 0;
	cin >> V >> n;

	pack.resize(n + 1, 0);//0号作为根节点
	while (n--)
	{
		cin >> x1 >> y1;
		s.push_back(make_pair(x1, y1));
	}

	B(0, 0);
	cout << m << endl;
	//cout << "counter=" << counter<<endl;
	return 0;
}
/*
3 4
1 2
2 3
3 4
4 5

*/


 

0.0分

1 人评分

  评论区

  • «
  • »