Money Systems
采用给出的 n 种不同的面值的货币构成 v 有多少种不同的方案。每种货币的数量不限。
We use dynamic programming to count the number of ways to make n cents with the given coins. If we denote the value of the kth coin by c_k, then the recurrence is:
nway(n, k) = no. of ways to make n cents with the first k types of coins
nway(n, k) = nway(n, k-1) + nway(n-c_k, k)
到了第k种货币的时候,来构成n元,可以有两种方案,用前k-1种构成 or 用前k种构成。背包问题
到了编程过程中采用一维数组,而不用二维数组来处理,nway[j]表示构成j的数目。
在更新过程中,如果到了第k种货币,不用k即 nway(n, k) = nway(n, k-1), 所以不用更新代替的一维数组nway[k];只考虑采用k的情况:
nway[j] += nway[j-c];
随着不断读入新的货币面值,来不断地更新nway数组的值,当全部面值都读入以后即可得到解
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #define MAXTOTAL 10000 long long nway[MAXTOTAL+1]; void main(void) { FILE *fin, *fout; int i, j, n, v, c; fin = fopen("money.in", "r"); fout = fopen("money.out", "w"); assert(fin != NULL && fout != NULL); fscanf(fin, "%d %d", &v, &n); nway[0] = 1; for(i=0; i<v; i++) { fscanf(fin, "%d", &c); for(j=c; j<=n; j++) nway[j] += nway[j-c]; } fprintf(fout, "%lld\n", nway[n]); }