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

问题描述:

有一天,海盗们截获了一艘装满各种各样的古董的货船,每一件古董都价值连城,一旦打碎就失去了它的价值。虽然海盗船足够大,但载重量为c,每件古董都有自己的重量,海盗们如何把最多的宝贝装上海盗船。

问题分析:

贪心算法具有很强的主观性,如果你觉得最好的情况那它就是最好的。

对于这个问题,我们可以将古董的重量从小到大表示出来,然后从小到大相加起来与载重量相比较,即可求得最多可以放入的古董数量。

我们可以先将主函数大致勾勒:

int main()
{
	int c;  //船的容量
	int n;  //古董的数量
	cout << "请输入船的容量:" << endl;
	cin >> c;
	cout << "请输入古董的数量:" << endl;
	cin >> n;
	
	return 0;
}

我们可以再定义一个结构体用于记录古董的数据:

struct antique
{
	int weight;  //古董重量
	int remain = 0;  //用于判断该古董是否被装入船中
};

还可以添加一个数据将最初输入的古董排序;

事已至此,我们是不是还需要一个“输入”函数来将古董的重量?

void get_element(int n, antique antique[N])
{
	for (int i = 0; i < n; i++)
	{
		cout << "请输入第" << i + 1 << "古董的重量:" << endl;
		cin >> antique[i].weight;
	}
}

我们将在主函数中调用这个函数:

int main()
{
	int c;
	int n;
	antique antique[N];
	int w;
	cout << "请输入船的容量:" << endl;
	cin >> c;
	cout << "请输入古董的数量:" << endl;
	cin >> n;
	get_element(n, antique);
	
	return 0;
}

进行到这一步,本代码已经初具雏形。

我们现在还需要将这些古董的重量排序,这里采用的是冒泡排序:

void sort(int n, antique antique[N])
{
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			struct antique temp;
			if (antique[j].weight > antique[i].weight)
			{
				temp = antique[j];
				antique[j] = antique[i];
				antique[i] = temp;
			}
		}
	}
}

我们接下来还要进行判断,判断古董的重量跟数量:

int antique_load(int c, int n, antique antique[N])
{
	int load_weight = 0;  //用于计算拿走的古董的重量
	int i = 0;  //用于统计古董被拿走的数量
	while (load_weight <= 30 && i < n)  //判断程序进行的条件
	{
		load_weight += antique[i].weight;
		antique[i].remain = 1;
		i++;
	}
	return i - 1;  //由于我们使用的是i++,最后数量是多出来一个的所以要-1
}

代码已经基本完成,接下来是完整代码:

#include <iostream>
using namespace std;
#define N 50

struct antique
{
	int weight;
	int remain = 0;
};
void get_element(int n, antique antique[N])
{
	for (int i = 0; i < n; i++)
	{
		cout << "请输入第" << i + 1 << "古董的重量:" << endl;
		cin >> antique[i].weight;
	}
}

void sort(int n, antique antique[N])
{
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			struct antique temp;
			if (antique[j].weight > antique[i].weight)
			{
				temp = antique[j];
				antique[j] = antique[i];
				antique[i] = temp;
			}
		}
	}
}
int antique_load(int c, int n, antique antique[N])
{
	int load_weight = 0;
	int i = 0;
	while (load_weight <= 30 && i < n)
	{
		load_weight += antique[i].weight;
		antique[i].remain = 1;
		i++;
	}
	return i - 1;
}

int main()
{
	int c;
	int n;
	antique antique[N];
	int w;
	cout << "请输入船的容量:" << endl;
	cin >> c;
	cout << "请输入古董的数量:" << endl;
	cin >> n;
	get_element(n, antique);
	sort(n, antique);
	w = antique_load(c, n, antique);
	cout << "共" << w << "个古董被拿走" << endl;
	for (int i = 0; i < n; i++)
	{
		cout << "第" << i + 1 << "古董的重量:" << antique[i].weight;
		if (antique[i].remain == 1)
			cout << "被海盗拿走" << endl;
		else cout << "未被海盗拿走" << endl;
	}
	return 0;
}

这里的代码并不足够好,main函数中最后几段循环代码还可以改进,博主的本意是打印出初始顺序下拿走的古董,但是未能完全实现,大家可以尝试把代码优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值