100元换零钱1元,2元,5元,10元,20元,50元有多少种组合方案
一道笔试题,当时就懵逼了。。。
找到递推公式之后,其实也不难
F(N,M)=F(N,M-1)+F(N-VAL[M],M)
F(N,M)表示 用不超过第M个值的数来表示N 的所有组合方案
举个栗子
我们先看4的组成
4 = 2+2 = 2+1+1 = 1+1+1+1共3种方案
我们再看公式,例如
F(4,6) = F(4,5) + F(4-VAL[6],6)
= F(4,5) + F(4-50,6)
= F(4,5) + F(-46,6)
= F(4,5)
F(4,5) = F(4,4) + F(4-VAL[5],5)
明显F(4,1)所代表的方案就是4=1+1+1+1,即F(4,1)=1
= F(4,4) + F(4-20,5)
= F(4,4) + F(-16,5)
= F(4,4)
F(4,4)
= F(4,3) + F(4-VAL[4],4)
= F(4,3) + F(4-10,4)
= F(4,3) + F(-6,4)
= F(4,3)
F(4,3) = F(4,2) + F(4-VAL[3],3)
= F(4,2) + F(4-5,3)
= F(4,2) + F(-1,3)
= F(4,2)
F(4,2) = F(4,1) + F(4-VAL[2],2)
F(4,6) 的所有组合方案其实就是F(4,2)的组合方案,毕竟VAL[3]~VAL[6]均大于4,不可能存在更多的组合方案,
= F(4,1) + F(4-2,3)
= F(4,1) + F(2,3)
= F(4,1) + F(2,3)
所以,
用不超过第6个值的数(即50元)来表示4元 的所有组合方案【F(4,6)】
等于 用不超过第2个值的数(即2元)来表示4元 的所有组合方案【F(4,2)】
那么,
用不超过第2个值的数(即2元)来表示4元 的所有组合方案【F(4,2)】
又等于
用不超过第1个值的数(即1元)来表示4元 的所有组合方案
加上
用不超过第3个值的数(即5元)来表示2元 的所有组合方案【F(4,1)+F(2,3)】
而F(2,3)也可以用上述推导的方式,即F(2,3)=F(2,2)=F(2,1)+F(0,2)=....=F(2,1)+F(0,0)=2
F(0,0)可以理解成用0元来表示0元,这算是1种方案
此时我们就能看出4的组合方案,其实就是
4=2+2
4=2+1+1
【F(4-VAL[2],2),意味着把红色数字减去 ,即F(2,2)代表上面两种方案】
4=1+1+1+1
【F(4,1)代表4=1+1+1+1方案】
代码如下:
int main()
{
int val[7] = { 0,1,2,5,10,20,50 };
int f[101][7];
memset(f, 0, sizeof(f));
for (int j = 0; j <= 6; j++)
f[0][j] = 1;
for (int j = 1; j <= 6; j++)
{
for (int i = 1; i <= 100; i++)
{
if (i - val[j] < 0)
f[i][j] = f[i][j - 1];
else
f[i][j] = f[i - val[j]][j] + f[i][j - 1];
}
}
//cout << test(0, 100) << endl;
//cout << ans << endl;
cout << f[100][6] << endl;
system("pause");
return 0;
}