找零问题_动态规划

// 找零问题_动态规划.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


#include<iostream> 
#include<stdlib.h> 
using namespace std ; 

void MinCoin(int NumOfValue , int Money  , int *CoinValue , int *OutCoin); 

/*
*    假如面值为{1,2,5}的钱币, 现在需要需要找得钱为18元,求所需要找钱最少的张数
*    NumOfValue : 3
*    Money      : 18
*    CoinValue  : {1,2,5}
*    OutCoin    : [1-18] 表示 1-18中需要找的钱的最少值 
*                 譬如 OutCoin[7] 表示要找7元时所需要的最少张数 
*                      OutCoin[8] 表示要找8元时所需要的最少张数
*
*/

void MinCoin(int NumOfValue , int Money  , int *CoinValue, int *OutCoin)
{ 
    /* 
    * 因为动态规划需要从之前的状态推导当前的状态
    * 所以必须先初始化之前的状态 OutCoin[0]
    */
    OutCoin[0] = 0;  

    //从1元开始,算出1,2,3....Money中每一个需要找得钱数所对应的最少张数
    for (int curMoney=1; curMoney<=Money; ++curMoney) 
    {
		// 目的是要求出在当前的curMoney的情况下,所需要找得最少钱数 -> OutCoin[curMoney] = MinCoin
        int MIN = curMoney; 

        /*
        * 轮询每一个币值,
        * 找出当前的钱数减去硬币面值,所得出之前的OutCoin的最小值
        * 然后+1,就是当前钱数所需找得最少值
        * 
        * 譬如说现在curMoney:9, 已经得出了OutCoin[8] = X, OutCoin[7] = Y, OutCoin[4] = Z
        * 现在就要比较 X, Y, Z的最小值 Mini
        * 结果就是 Mini + 1;
        */
        for (int ValueIdx = 0; ValueIdx < NumOfValue; ++ValueIdx) 
        {
            if (curMoney - CoinValue[ValueIdx] >= 0)
            {
                //求出OutCoin[MoneyId-ValueIdx]所找得最少张数
                if (OutCoin[curMoney-CoinValue[ValueIdx]] < MIN) 
                {
                    MIN = OutCoin[curMoney-CoinValue[ValueIdx]];
                }
            }
        }
        OutCoin[curMoney] = MIN+1;
    }
}

int main() 
{ 
    int a[]={1, 2 , 5} ; 
    int c[18+1]={0} ; 
 
    MinCoin(3 , 18 , a , c) ; 
    cout << "最优解就是最少值为:" << c[18] << endl ;
    for(int i=1 ; i<19 ; i++) 
        cout << c[i] << " " ; 
    system("pause") ; 
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值