描述
给一些不同价值和数量的硬币。找出[1,n]范围内的总值有多少种形成方式?
题目链接:https://www.lintcode.com/problem/799/
方法一:递归
#include "iostream"
#include "vector"
#include "cstring"
using namespace std;
int process(vector<int> &value, vector<int> &amount, int index, int n) {
if (index == value.size()) {
return n == 0 ? 1 : 0;
}
int way = 0;
for(int i = 0; i <=amount[index]; i++){
way = way || (process(value, amount, index + 1, n) || process(value, amount, index + 1, n - i * value[index]));
}
return way;
}
int main(){
vector<int> value;
value.push_back(1);
value.push_back(2);
value.push_back(4);
vector<int> amount;
amount.push_back(2);
amount.push_back(1);
amount.push_back(1);
int n = 10;
int ans = 0;
for(int i = 1; i <= n; i++){
ans += process(value, amount, 0, i);
}
cout << ans;
return 0;
}
方法二:dp(二维数组)
class Solution {
public:
/**
* @param n: the value from 1 - n
* @param value: the value of coins
* @param amount: the number of coins
* @return: how many different value
*/
int backPackVIII(int n, vector<int> &value, vector<int> &amount) {
// write your code here
int dp[value.size() + 1][n + 1];
memset(dp, 0, sizeof(dp));
dp[value.size()][0] = 1;
for(int i = value.size() - 1; i >= 0; i--){
for(int j = 0; j <= n; j++){
dp[i][j] = dp[i][j] || dp[i + 1][j];
if(dp[i][j] == 1){
continue;
}
for(int k = 0; k <= amount[i] && k * value[i] <= j; k++){
dp[i][j] = dp[i][j] || dp[i + 1][j - k * value[i]];
if(dp[i][j] == 1){
break;
}
}
}
}
int ans =0;
for(int i = 1; i <= n; i++){
ans += dp[0][i];
}
return ans;
}
};
方法三:dp(一维数组)
#include "iostream"
#include "vector"
#include "cstring"
using namespace std;
int main(){
vector<int> value{1,2,4};
vector<int> amount{2,1,1};
int n = 10;
vector <int> dp(n + 1);
dp[0] = 1;
int sum = 0;
for (int i = 0; i < value.size(); i++) {
for (int j = 0; j <= n; j++) {
//之前已经组成的,那么本次就可以传递 amount[i] 次。
if (dp[j] >= 1) {
dp[j] = amount[i] + 1;
} else if (j >= value[i] && dp[j - value[i]] >= 2) {
//之前标记的 amount[j - value[i]] > 1 说明还没传递完,继续传递
dp[j] = dp[j - value[i]] - 1;
}
}
}
for (int i = 1; i <= n; i++) {
if (dp[i] >= 1) {
sum++;
}
}
cout << sum;
return 0;
}