CSDN题目:凑硬币问题

这是一个背包问题,但是我要的不是这些,第一个给出背包代码的,20分。其他的不给分。

给出我要的结果的,又分。

我要什么结果呢?先看题目。
你有(足够的)5分,2分,1分的硬币,现在要凑出来12分的结果,那么最少的硬币组合是?

结果肯定是 【5 5 2】


那么给你的硬币是 5分的,4分的(虽然我没有见过),1分的,凑8分,怎么凑?
贪婪算法可能给出 【5 1 1 1】,但是显然应该是【4 4】

我现在要的代码  是那10行背包代码。  

而是要能输出需要哪些硬币的结果,比如对于5,4,1凑8这个,你要输出4,4。

我不关注是2枚硬币,还是3枚。


用回溯法求解:

#include <iostream>
#include <vector>

using namespace std;

int array[] = {5, 4, 1};
const int size = sizeof array / sizeof *array;

vector<vector<int> > ivecs;
vector<int> ivec;

void generateCandidates(int *array, int size, int index, int *candidates, int &ncandidate)
{
	if (array == NULL || size <= 0)
		return;

	ncandidate = 0;
	for (int i = index; i < size; i++)
	{
		candidates[i - index] = array[i];
		ncandidate++;
	}
}

bool isSolution(int sum)
{
	if (sum == 0)
		return true;
	else
		return false;
}

void process(vector<vector<int> > &ivecs, vector<int> &ivec)
{
	ivecs.push_back(ivec);
}

void process(int *array, int size, int *states, int &index, vector<vector<int> > &ivecs, vector<int> &ivec, int sum)
{
	if (array == NULL || size <= 0 || states == NULL)
		return;

	if (sum < 0)
	{
		return;
	}

	int candidates[100];
	int ncandidate;
	if (isSolution(sum) == true)
		process(ivecs, ivec);
	else
	{
		generateCandidates(array, size, index, candidates, ncandidate);
		for (int i = 0; i < ncandidate; i++)
		{
			sum -= candidates[i];
			ivec.push_back(candidates[i]);
			for (int m = 0; m < size; m++)
			{
				if (array[m] == candidates[i])
					index = m;
			}
			process(array, size, states, index, ivecs, ivec, sum);
			ivec.pop_back();
			sum += candidates[i];
		}     
	}
}

void main()
{
	int states[size];
	int index = 0;
	int sum = 8;
	process(array, size, states, index, ivecs, ivec, sum);
	int minNumber = 65535;
	int pos;
	for (int i = 0; i < ivecs.size(); i++)
	{
		if (minNumber > ivecs[i].size())
		{
			pos = i;
			minNumber = ivecs[i].size();
		}
	}

	copy(ivecs[pos].begin(), ivecs[pos].end(), ostream_iterator<int>(cout, " "));
}


迭代算法简单易懂

#include <iostream>
#include <vector>

using namespace std;

int array[] = {5, 4, 1};
const int size = sizeof array / sizeof *array;

vector<vector<int> > ivecs;
vector<int> ivec;

void getCoins(int *array, int size, int total)
{
	if (array == NULL || size <= 0)
		return;

	int leftIndex = 0;
	int rightIndex = 0;
	int totalCount = 0;
	int count = 0;
	int value = total;

	while (leftIndex != size)
	{
		while (rightIndex != size)
		{
			count = value / array[rightIndex];
			if (count != 0)
			{
				for (int i = 0; i < count; i++)
					ivec.push_back(array[rightIndex]);
			}
			value = value % array[rightIndex];
			rightIndex++;
		}

		if (value == 0)
		{
			ivecs.push_back(ivec);
			ivec.clear();
		}

		leftIndex++;
		rightIndex = leftIndex;
		value = total;
	}

	int minNumber = 65535;
	int pos;
	for (int i = 0; i < ivecs.size(); i++)
	{
		if (minNumber > ivecs[i].size())
		{
			pos = i;
			minNumber = ivecs[i].size();
		}
	}

	copy(ivecs[pos].begin(), ivecs[pos].end(), ostream_iterator<int>(cout, " "));
}

void main()
{
	int sum = 38;
	getCoins(array, size, sum);
}



你可能感兴趣的:(CSDN题目:凑硬币问题)