2014华为编程大赛题目:笨笨熊搬家打包篇

题目:笨笨熊搬家打包篇

森林里的笨笨熊今天可开心啦——他买了新房子,乔迁新喜要搬家了。

因此,笨笨熊请了许多好朋友来帮忙搬家,并准备了很多小纸盒用来装需要搬的物品,
不过,这些纸盒的容积都是相同的,并且最多只能装两个物品。
但是,为了不打扰太多的朋友,笨笨熊想了个“聪明”办法:让每个纸盒使用效率最高
(注:只要纸盒容积大于物品的体积之和就认为可以装下;物品体积不会大于纸盒容积),
这样需要的纸盒最少。为了帮助笨笨熊提前通知朋友,请你根据笨笨熊的办法,
帮忙算出:需要纸盒的最少数目是多少?


输入:
V: 整数V——纸盒的容积; 
整数N: 物品的总数目N;  
数组objects: 共N个整数(对应N个物品的体积,每个整数用空格隔开)。    
输出:   整数M——需要纸盒的最少数目;           
样例输入:  
10 
2  
2 3  

样例输出:  1 


思路1:排序,最大者加上可加的次大者

#include "stdafx.h"
#include "iostream"

using namespace std;

int LeastBox(int V, int N, int * objects)
{
	if (N < 1)
	{
		return 0;
	}
	if (N < 2)
	{
		return 1;
	}
	int box = 0;

	// 插入排序
	if (objects[0] < objects[1])
	{
		int tmp = objects[1];
		objects[1] = objects[0];
		objects[0] = tmp;
	}
	for (int i = 2; i < N; i++)
	{
		for (int j = i; j > 0; j--)
		{
			if (objects[j] > objects[j - 1])
			{
				int tmp = objects[j];
				objects[j] = objects[j - 1];
				objects[j - 1] = tmp;
			}
			else
			{
				break;
			}
		}
	}

	// 体积最大者加上某一体积物体,该物体体积是满足两物相加体积不超过V的最大值
	for (int i = 0; i < N; i++)
	{
		if (objects[i] == 0)
		{
			continue;
		}
		for (int j = i + 1; j < N; j++)
		{
			if (objects[j] == 0)
			{
				continue;
			}
			if (objects[i] + objects[j] <= V)
			{
				objects[i] = 0;
				objects[j] = 0;
				box ++;
			}
		}
		if (objects[i] != 0)
		{
			objects[i] = 0;
			box ++;
		}
	}
	return box;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int V = 0;
	int N = 0;
	int * objects = NULL;
	cout << "盒子容积:";
	cin >> V;
	cout << "物品数:";
	cin >> N;
	objects = new int[N];
	cout << "详细物品体积:";
	for (int i = 0; i < N; i++)
	{
		cin >> objects[i];
	}
	cout << "最少的盒子数目为:" << LeastBox(V, N, objects) << endl;
	delete [] objects;
	system("pause");
	return 0;
}

思路2:排序,最大者加上最小者

#include "stdafx.h"
#include "iostream"

using namespace std;

int LeastBox(int V, int N, int * objects)
{
	if (N < 1)
	{
		return 0;
	}
	if (N < 2)
	{
		return 1;
	}
	int box = 0;

	// 插入排序
	if (objects[0] < objects[1])
	{
		int tmp = objects[1];
		objects[1] = objects[0];
		objects[0] = tmp;
	}
	for (int i = 2; i < N; i++)
	{
		for (int j = i; j > 0; j--)
		{
			if (objects[j] > objects[j - 1])
			{
				int tmp = objects[j];
				objects[j] = objects[j - 1];
				objects[j - 1] = tmp;
			}
			else
			{
				break;
			}
		}
	}


	// 最大者加上最小者
	int i = 0;
	int j = N - 1;
	while (i < j)
	{
		if (objects[i] + objects[j] <= V)
		{
			i++;
			j--;
			box++;
			continue;
		}
		else
		{
			i++;
			box++;
			continue;
		}
	}
	return box;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int V = 0;
	int N = 0;
	int * objects = NULL;
	cout << "盒子容积:";
	cin >> V;
	cout << "物品数:";
	cin >> N;
	objects = new int[N];
	cout << "详细物品体积:";
	for (int i = 0; i < N; i++)
	{
		cin >> objects[i];
	}
	cout << "最少的盒子数目为:" << LeastBox(V, N, objects) << endl;
	delete [] objects;
	system("pause");
	return 0;
}


两个思路我稍想了一下应该都是对的,没有想出严格的数学依据,也没有找出反例,求指点。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值