1. 问题描述:
n种硬币,面值分别是:v[1],v[2],……v[n]。给定非负整数s,可以选用多少个硬币,使得面值之和恰好为s?求出硬币数目的最大值和最小值。
2. 分析:
初始状态为:S,目标状态为0。若当前状态在i,每使用一个硬币j,状态便转移到i-v[j]。我们用d(i)表示求总和为i的最少硬币数量(其实就是动态规划中的“状态”),那么怎么从前面的状态(并不一定是d(i-1)这一个状态)到d(i)这个状态?假设硬币集合为coins[0~N],在求d(i)之前,我们假设d(1~i-1)全部都求出来了,那么d(i)=min{d(i-v[j])+1}(其实这就是“状态转移方程”)。
举例说明:coins={2,3,5},N=11。
d(0)=0;
d(1)=0;
d(2)=d(0)+1=1;
d(3)=d(0)+1=1;
d(4)=d(2)+1=2;
d(5)=min{d(3)+1,d(2)+1,d(0)+1}=1;
d(6)=min{d(4)+1,d(3)+1}=2;
……
3. 记忆化搜索代码:
#include<iostream>
#include<cstring>
using namespacestd;
int n, s, v[100],d[100], vi