又是一道动态规划的题,真的类似于0-1背包问题.在提示之下解决了,总算是解决了.虽然没费多少劲.
这个东西,没有用面向对象的方式写.体验了一把,结构化.对于参数传递,共享数据,的确不及类方便.
这种问题的状态转移方程,没有写对.我找错了状态.这段时间看<<代码大全>>,感觉自己的代码风格有所好转.虽然觉得过去的也不错,但是也没有现在的好.
再说下问题的实质吧:给定硬币的面值集合与总钱数,给出最少硬币数的找钱组合.
真的,写出来之后,不想说太多了.帖吧.
// ITA16-1.cpp -- 2011-07-19-18.00
#include "stdafx.h"
#include <iostream>
#include <assert.h>
typedef int KindOfCoin ;
const int KSIZE = 3 ;
const int INFINITY = ~(1 << 31) ;
KindOfCoin * g_kindRecord = NULL ;
int g_kRSize ;
int minNumberofCoins (const int sumMoney, const KindOfCoin * const kind, const int kSize) ;
void insertionSort (KindOfCoin * const kind, const int kSize) ;
int indexOfDenominationInKind (const KindOfCoin * const kind, const int kSize, const KindOfCoin denomination) ;
void printUsedCions (KindOfCoin * const kind, const int kSize) ;
void initializeGlobalValue (const int sumMoney) ;
void freeGlobalValue (void) ;
int _tmain(int argc, _TCHAR* argv[])
{
KindOfCoin kind[KSIZE] = {4, 1, 6} ;
int sumMoney = 50 ;
std ::cout << "Number of icons: " << minNumberofCoins(sumMoney, kind, KSIZE) << std ::endl ;
printUsedCions(kind, KSIZE) ;
freeGlobalValue() ;
return 0 ;
}
int minNumberofCoins (const int sumMoney, const KindOfCoin * const kind, const int kSize)
{
int * minNum = new int[sumMoney + 1] ;
minNum[0] = 0 ;
initializeGlobalValue(sumMoney) ;
for (int currentMoney = 1; currentMoney <= sumMoney; ++currentMoney)
{
minNum[currentMoney] = INFINITY ;
for (int denominationIndex = kSize - 1; denominationIndex >= 0; --denominationIndex)
{
if (currentMoney >= kind[denominationIndex] && 1 + minNum[currentMoney - kind[denominationIndex]] < minNum[currentMoney])
{
minNum[currentMoney] = 1 + minNum[currentMoney - kind[denominationIndex]] ;
g_kindRecord[currentMoney] = kind[denominationIndex] ;
}
}
}
int minNumberOfIcons = minNum[sumMoney] ;
delete []minNum ;
return minNumberOfIcons ;
}
void insertionSort (KindOfCoin * const kind, const int kSize)
{
for (int i = 1; i < kSize; ++i)
{
KindOfCoin temp = kind[i] ;
int j = i ;
while (j >= 0)
{
if (kind[j - 1] > temp)
{
kind[j] = kind[j - 1] ;
--j ;
}
else
break ;
}
kind[j] = temp ;
}
}
int indexOfDenominationInKind (const KindOfCoin * const kind, const int kSize, const KindOfCoin denomination)
{
for (int i = 0; i < kSize; ++i)
{
if (kind[i] == denomination)
return i ;
}
// else error
assert(0) ;
}
void printUsedCions (KindOfCoin * const kind, const int kSize)
{
assert(g_kindRecord != NULL) ;
using std ::cout ;
using std ::endl ;
int * numRecord = new int[kSize] ;
for (int i = 0; i < kSize; ++i)
numRecord[i] = 0 ;
insertionSort(kind, kSize) ;
int i = g_kRSize - 1 ;
while (i > 0)
{
++numRecord[indexOfDenominationInKind(kind, kSize, g_kindRecord[i])] ;
i -= g_kindRecord[i] ;
}
// print
for (int i = kSize - 1; i >= 0; --i)
{
if (numRecord[i] != 0)
cout << "Denomination[" << kind[i] << "]: " << numRecord[i] << endl ;
}
delete []numRecord ;
}
void initializeGlobalValue (const int sumMoney)
{
g_kRSize = sumMoney + 1 ;
if (NULL == g_kindRecord)
g_kindRecord = new int[g_kRSize] ;
else
{
delete []g_kindRecord ;
g_kindRecord = new int[g_kRSize] ;
}
for (int i = 0; i < g_kRSize; ++i)
g_kindRecord[i] = 0 ;
}
void freeGlobalValue (void)
{
delete []g_kindRecord ;
g_kindRecord = NULL ;
}