贪心算法之加勒比海盗船最优装载问题

1、问题

在北美洲东南部,有一片神秘的海域,那里碧海蓝天、阳光明媚,这正是传说中海盗最活跃的加勒比海,这里更是欧洲大陆的商旅舰队到达美洲的必经之地,所以当时的海盗活皇家舰……动非常猖獗,海盗不仅攻击过往商人,甚至攻击英国有一天,海盗们截获了一艘装满各种各样古董的货船,每一件古董都价值连城,一旦打碎就失去了它的价值。虽然海盗船足够大,但载重量为 C,每件古
董的重量为 w i ,海盗们该如何把尽可能多数量的宝贝装上海盗船呢?

2、分析

注意这里的每个物品的价值一样,我们可以用贪心算法,放得最多肯定最好,我们每次从最小重量古董开始放,直到放不下未知

我们先排序。然后每次放最小的重量古董。

贪心策略:每次放最小的重量古董

3、代码实现

普通实现:

#include <iostream>
#include <algorithm>

using namespace std;

//记得这里不是const int M 1000;
//因为不是宏,下次不要犯这个错

const int M = 1000;
double data[M];

int main()
{
	std::cout << "请输入船的载重和所有宝物的总数量(不要超过1000)" << std::endl;
	//all为宝物的总数,count是最多可以存放多少宝物的数量
	int weight = 0, all = 0, count = 0;
	std::cin >> weight >> all;
	if (weight <= 0 || all <= 0 || all > 1000) 
	{
		std::cout << "输入有误" << std::endl;
		return 0;
	}
	std::cout << "您输入的载重为" << weight << ",宝贝的数量为" << all << std::endl;
	std::cout << "请分别输入每个宝物的重量" << std::endl;
	for (int i = 0; i < all; ++i) 
	{
		std::cin >> data[i];
	}
	//然后我们用sort进行排序
	sort(data, data + all);
	double sum = 0, index = 0;
	for (int i = 0; i < all; ++i) 
	{

		if (sum + data[i] <= weight)
		{
			sum += data[i];
			++count;
			index = i;
		}
//  注意我下面这样写是错误的,逻辑上有问题,先分析清楚再来写
//		if (sum <= weight) 
//		{
//			sum += data[i];
//			++count;
//			index = i;
//		}
		else
			break;
	}
	std::cout << "船最多可以装下" << count << "个宝物" << std::endl;
	std::cout << "需要装上船的宝物重量分别为" << std::endl;
	for (int i = 0; i <= index; ++i) 
	{
		std::cout << data[i] << "\t";
	}
	std::cout << std::endl;
	return 0;	
}

类方式实现:

#include <iostream>
#include <algorithm>

using namespace std;

//记得这里不是const int M 1000;
//因为不是宏,下次不要犯这个错

const int M = 1000;
double data[M];

class jialebi
{
public:
	void init();
	void resolve();
private:
	//all为宝物的总数,count是最多可以存放多少宝物的数量
	int weight, all, count;
};

void jialebi::init()
{
	std::cout << "请输入船的载重和所有宝物的总数量(不要超过1000)" << std::endl;
	std::cin >> weight >> all;
	if (weight <= 0 || all <= 0 || all > 1000) 
	{
		std::cout << "输入有误" << std::endl;
		return;
	}
	std::cout << "您输入的载重为" << weight << ",宝贝的数量为" << all << std::endl;
	std::cout << "请分别输入每个宝物的重量" << std::endl;
	for (int i = 0; i < all; ++i) 
	{
		std::cin >> data[i];
	}

}

void jialebi::resolve()
{
	//然后我们用sort进行排序
	sort(data, data + all);
	double sum = 0, index = 0;
	for (int i = 0; i < all; ++i) 
	{

		if (sum + data[i] <= weight)
		{
			sum += data[i];
			++count;
			index = i;
		}
		else
			break;
	}
	std::cout << "船最多可以装下" << count << "个宝物" << std::endl;
	std::cout << "需要装上船的宝物重量分别为" << std::endl;
	for (int i = 0; i <= index; ++i) 
	{
		std::cout << data[i] << "\t";
	}
	std::cout << std::endl;
	
}
int main()
{
	jialebi jia;
	jia.init();
	jia.resolve();
	return 0;	
}

4、运行结果

/**
请输入船的载重和所有宝物的总数量(不要超过1000)
20 6
您输入的载重为20,宝贝的数量为6
请分别输入每个宝物的重量
2 3 4 5 6 7
船最多可以装下5个宝物
需要装上船的宝物重量分别为
2	3	4	5	6	
**/

5、总结

我们用贪心算法的时候,最关键的是需要找出贪心策略,这里的贪心策略是每次都取重量最小的古董,这里和冒泡排序的性质差不多,然后就是我们每次求出一步后都是最优解,然后后面的问题又可以按照同样的方式求解,所以这个时候我们应该用贪心算法

    原文作者:贪心算法
    原文地址: https://blog.csdn.net/u011068702/article/details/79038757
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞