1. 程式人生 > >硬幣面值組合(上臺階)

硬幣面值組合(上臺階)

給定一個數值sum,假設我們有m種不同型別的硬幣{V1, V2, ..., Vm},如果要組合成sum,那麼我們有

sum = x1 * V1 + x2 * V2 + ... + xm * Vm 

求所有可能的組合數,就是求滿足前面等值的係數{x1, x2, ..., xm}的所有可能個數。

dp[i][sum] = 用前i種硬幣構成sum 的所有組合數。

  那麼題目的問題實際上就是求dp[m][sum],即用前m種硬幣(所有硬幣)構成sum的所有組合數。

dp[i][sum] = dp[i-1][sum - 0*Vm] + dp[i-1][sum - 1*Vm]

+ dp[i-1][sum - 2*Vm] + ... + dp[i-1][sum - K*Vm]; 其中K = sum / Vm

那麼初始情況是什麼呢?如果sum=0,那麼無論有前多少種來組合0,只有一種可能,就是各個係數都等於0;

dp[i][0] = 1   // i = 0, 1, 2, ... , m

我們規定為dp[0][sum] = 0. 

#include<iostream>
#include<vector>
using namespace std;


int coinCombination(int coin[], int coinKinds, int target){
	vector<vector<int> >dp(coinKinds + 1, vector<int>(target + 1));

	for (int i = 0; i <= coinKinds; i++){
		dp[i][0] = 1;
	}

	dp[0][target] = 0;

	for (int i = 1; i <= coinKinds; i++){
		for (int j = 1; j <= target; j++){
			dp[i][j] = 0;
			for (int k = 0; k <= j / coin[i - 1]; k++){//<=
				dp[i][j] += dp[i - 1][j - k*coin[i - 1]];//+=
			}
		}
	}

	return dp[coinKinds][target];
}


int main(){

	int coin[4] = { 1, 2, 5, 10 };

	cout << coinCombination(coin, 4, 5) << endl;

	return 0;
}

http://www.cnblogs.com/python27/p/3303721.html