【问题描述】有n种不同面值的硬币,各硬币面值存于数组T[1:n];现用这些面值的钱来找钱;各面值的个数存在数组Num[1:n]中。
【编程任务】对于给定的1<=n<=10,硬币面值数组、各面值的个数及钱数m,0<=m<=2001,编程计算找钱m的最少硬币数。
input : 第一个数字n,后面n行每行两个数,面值T[i],面值个数Num[i];最后是钱数m。
output:最少硬币数。
Sample intput :
3
1 3
2 3
5 3
18
Sample output:
5
【分析】:一看大家都会觉得最优子结构是 dp(m)=max{dp(m-t[i])+1},但是面值的个数在哪里?不好考虑。我开始以为状态跟面值、个数、钱数三个因素有关,应该要有个三维数组来存储状态,其实不然,那样的话动态规划的优势就没啦!对动态规划的理解还在“成长阶段”呀!废话少说,切入正题!
先看状态方程,状态方程一出,程序应该就ok了!
用MianZhi[1:m]和Mian_Zhi[1:m]来表示面值为i时的最少硬币数。TV[1:N]来表示某种面值的所有钱数,即TV[i]=T[i]*Num[i];
MianZhi[i]=min{MianZhi[i-T[j]*t]+t} t表示面值为T[j]的个数
T[j]<=i<=m; 2<=j<=N; (j = 1 另行考虑,动态规划必须的起点)
当j=1时 MianZhi[i]=Mian_Zhi[i]=i/T[1]; (1<=i<=m;i%T[1]==0&&i<=TV[1])
MianZhi[0]=Mian_Zhi[0]=0;