方法1,动态规划,最快。方法2递归有点慢,方法三递归,超级慢。在aim数值大于30的时候,三种写法,在我电脑速度快慢特别明显。用2元,3元,5元去找开100块,用递归方法,我的电脑要等到地老天荒O(∩_∩)O哈哈~
#include<iostream>
#include<vector>
using namespace std;
int dp_solve(int *a, int n, int aim){
vector<vector<int>> dp(n, vector<int>(aim+1, 0));
for(int j = 1; j <= aim; j++){
dp[0][j] = INT_MAX;
if(j >= a[0] && dp[0][j - a[0]] != INT_MAX)
dp[0][j] = dp[0][j - a[0]] + 1;
}
for(int i = 1; i < n; i++){
for(int j = 1; j <= aim; j++)
{
int tmp = INT_MAX;
if(j - a[i] >= 0 && dp[i][j - a[i]] != INT_MAX)
tmp = dp[i][j - a[i]] + 1;
dp[i][j] = min(dp[i-1][j], tmp);
}
}
return dp[n-1][aim] == INT_MAX ? -1 : dp[n-1][aim];
}
int min_res = INT_MAX;
void recur_solve(int *a, int n, int aim, int k){
if(aim == 0){
min_res = min(min_res, k);
return;
}
if(aim < 0)
return;
for(int i = 0; i < n; i++){
aim -= a[i];
k++;
recur_solve(a, n, aim, k);
aim += a[i];
k--;
}
}
int min_res2 = INT_MAX;
void recur_solve2(int *a, int n, int aim, vector<int> res){
if(aim == 0){
int size = res.size();
min_res2 = min(min_res2, size);
return;
}
if(aim < 0)
return;
for(int i = 0; i < n; i++){
res.push_back(a[i]);
recur_solve2(a, n, aim - a[i], res);
res.pop_back();
}
}
int main(){
int a[] = {2,3,7};
int sum = 25;
/***dp最快**/
cout << dp_solve(a, 3, sum) << endl;
/***这种递归有点久**/
recur_solve(a, 3, sum, 0);
cout << min_res << endl;
/**这个太久了**/
vector<int> result;
recur_solve2(a, 3, sum, result);
cout << min_res2 << endl;
return 0;
}
展开