硬币找零
假设有几种硬币,如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;
}