这是一个背包问题,但是我要的不是这些,第一个给出背包代码的,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。
给出我要的结果的,又分。
我要什么结果呢?先看题目。
你有(足够的)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);
}