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