给定一些硬币的面值(不超过20种),每种硬币有无数个,求能组成target值(不超过11000000)的最小硬币数,以及相应的面值。如果不能,输出“No solution”。
INPUT:
4
1 3 4 9
6
OUTPUT:
2
3 3
INPUT:
4
2 3 4 9
1
OUTPUT:
No solution
动态规划算法,但是复杂度较高#_#。
用value[i]记录凑到i时最后选取的面值,然后循环求解所有用到的面值~
#include<bits/stdc++.h>
using namespace std;
const int maxn = 22;
const int maxm = 11000000;
int dp[maxm]; // dp[i]组成面值为i的最小硬币数
int value[maxm];
void solve(int target, int n, int a[]){
dp[0] = 0;
for(int i = 1; i <= target; i++){
dp[i] = INT_MAX;
for(int j = 0; j < n; j++){
if(a[j] <= i){
if(dp[i-a[j]]+1 < dp[i]){
dp[i] = dp[i-a[j]]+1;
value[i] = a[j];
}
}
}
}
}
int main(){
int target;
int a[maxn];
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", a+i);
scanf("%d", &target);
solve(target, n, a);
if(dp[target] == INT_MAX)
printf("No solution\n");
else{
printf("%d\n", dp[target]);
while(target > 0){
printf("%d ", value[target]);
target -= value[target];
}
}
return 0;
}