动态规划之找零问题

硬币找零问题描述:现存在一堆面值为 V1、V2、V3 … 个单位的硬币,问最少需要多少个硬币才能找出总值为 T 个单位的零钱?假设这一堆面值分别为 1、2、5、21、25 元,需要找出总值 T 为 63 元的零钱。

// Coin.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"
#include "string.h"
//int min = 0x7fffffff;
#define max(a,b) a>b?a:b
#define min(a,b) a>b?b:a
int d[10000];
int coinValue[5] = {25, 21, 10, 5, 1}; 
int cnt = 0;
int FindCoin(int num)//S个硬币的最大找零数
{
	if (d[num] >= 0)
		return d[num];
	int q = 0;
	for(int i = 0; i < 5; i++)
		if(num- coinValue[i] >= 0)
			q = max(q, FindCoin(num- coinValue[i])+1);
	
		
	d[num] = q;

	return q;
	
}

int FindCoinMin(int num)//S个硬币的最小找零数
{
	if (d[num] >= 0)
		return d[num];
	if (num == 0)
		return 0;
	int q = 0x7dFFFFFF;
	for(int i = 0; i < 5; i++)
		if(num - coinValue[i] >= 0)
			q = min(q, FindCoinMin(num - coinValue[i])+1);
		
		
	d[num] = q;
	
	return q;
		
}
/*
int FindMin(int num)
{
	if (num == 0)
		return 0;

	int q;
	//找到每层解答树的最小子树
	for (int i = 0; i < 5; i++)
	{
		if ((num - coinValue[i] >= 0)  && (min > d[(num - coinValue[i])]))
		{
			q = i;
			min = d[(num - coinValue[i])];
		}
			
	}

	return FindMin(num - coinValue[q])+1;


}*/
int main(int argc, char* argv[])
{

	int S;
	memset(d, -1, 10000*sizeof(int));
	scanf("%d", &S);
	printf("max:%d\n", FindCoin(S));

	//printf("min:%d", FindMin(S));
	memset(d, -1, 10000*sizeof(int));
	printf("min:%d", FindCoinMin(S));
	
	return 0;
}

其中FINDMIN函数有问题,因为最小子树不一定在最长子树中的最小子树中



非递归的方法,自底向上求解

// Coin.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"
#include "string.h"
//int min = 0x7fffffff;
#define max(a,b) a>b?a:b
#define min(a,b) a>b?b:a
int d[100];
int coinValue[5] = {25, 21, 10, 5, 1}; 
int cnt = 0;
/*int FindCoin(int num)//S个硬币的最大找零数
{
	if (d[num] >= 0)
		return d[num];
	int q = 0;					//会有问题不一定能到达q=0的状态,
	for(int i = 0; i < 5;  i++)
		if(num- coinValue[i] >= 0)
			q = max(q, FindCoin(num- coinValue[i])+1);
	
		
	d[num] = q;

	return q;
	
}

int FindCoinMin(int num)//S个硬币的最小找零数
{
	if (d[num] >= 0)
		return d[num];
	if (num == 0)
		return 0;
	int q = 0x7dFFFFFF;
	for(int i = 0; i < 5; i++)
		if(num - coinValue[i] >= 0)
			q = min(q, FindCoinMin(num - coinValue[i])+1);
		
		
	d[num] = q;
	
	return q;
		
}

int FindMin(int num)
{
	if (num == 0)
		return 0;

	int q;
	//找到每层解答树的最小子树
	for (int i = 0; i < 5; i++)
	{
		if ((num - coinValue[i] >= 0)  && (min > d[(num - coinValue[i])]))
		{
			q = i;
			min = d[(num - coinValue[i])];
		}
			
	}

	return FindMin(num - coinValue[q])+1;


}*/
int main(int argc, char* argv[])
{

	int S;
	memset(d, 0, 100*sizeof(int));
	scanf("%d", &S);
	/*printf("max:%d\n", FindCoin(S));

	//printf("min:%d", FindMin(S));
	memset(d, -1, 100*sizeof(int));
	printf("min:%d", FindCoinMin(S));*/
	

	d[0] = 0;
	int q;
	for(int i = 1; i <= S; i++)
	{
		q = 0;
		for(int j = 0; j < 5; j++)
			if ((i - coinValue[j]) >= 0)
				q = max(q,d[i - coinValue[j]]+1);		
		
		d[i] = q; 

	}
	printf("max:%d",q);	


	d[0] = 0;

	for(i = 1; i <= S; i++)
	{
		q = 0x7dffffff;
		for(int j = 0; j < 5; j++)
			if ((i - coinValue[j]) >= 0)
				q = min(q,d[i - coinValue[j]]+1);		
			
			d[i] = q; 
			
	}
	printf("min:%d",q);	
	return 0;
}


你可能感兴趣的:(动态规划之找零问题)