您的位置:首页 > 其它

算法练习 动态规划 硬币找零

2016-02-10 20:31 561 查看
硬币找零

假设有几种硬币,如1、3、5,并且数量无限。请找出能够组成某个数目的找零所使用最少的硬币数。 

解法:
  用待找零的数值k描述子结构/状态,记作sum[k],其值为所需的最小硬币数。对于不同的硬币面值coin[0...n],有sum[k] = min(sum[k-coin[0]] , sum[k-coin[1]], ...)+1。对应于给定数目的找零total,需要求解sum[total]的值。

#include<stdio.h>

#include<stdlib.h>

#include<iostream>

#include<queue>

#include<climits>

#include<cstring>

using namespace std;

#define INF 100000

typedef struct{

int nCoin;

int lastSum;

int addCoin;

}state;

int main()

{

    int total;//需要找的零钱总数

    int n;//总共有的零钱种类

    int coin[20];//存放零钱种类的数组

    cin>>n;

    for(int i=0;i<n;i++)

        cin>>coin[i];

    int count[20]={0};

    cin>>total;

    state *sum=(state*)malloc(sizeof(state)*(total+1));

    for(int i=0;i<=total;i++)

    {

        sum[i].nCoin=INF;

    }

    sum[0].nCoin=0;

    sum[0].lastSum=0;

    for(int i=1;i<=total;i++)

    {

        for(int j=0;j<n;j++)

            if(i-coin[j]>=0&&sum[i-coin[j]].nCoin+1<=sum[i].nCoin)

            {

            sum[i].nCoin=sum[i-coin[j]].nCoin+1;

            sum[i].lastSum=i-coin[j];

            sum[i].addCoin=coin[j];

            }

    }

        if(sum[total].nCoin==INF)

        {

            cout<<"cannot make change."<<endl;

        }

        else

        {

            cout<<sum[total].nCoin<<endl;

            int a=total;

            while(a)

            {

                for(int i=0;i<n;i++)

                if(sum[a].addCoin==coin[i])

                    count[i]++;

                a=sum[a].lastSum;

            }

            for(int i=0;i<n;i++)

            {

                if(count[i]!=0)

                    cout<<coin[i]<<"元"<<count[i]<<"个"<<endl;

            }

        }

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划 算法