算法导论16-1

   又是一道动态规划的题,真的类似于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 ;
}

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值