1. 程式人生 > >2014華為程式設計大賽題目:笨笨熊搬家打包篇

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;
}
兩個思路我稍想了一下應該都是對的,沒有想出嚴格的數學依據,也沒有找出反例,求指點。