DFS+剪枝
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4+10;
int coin[maxn];
int n,m;
bool vis[maxn]={false};
bool flag = false;
vector<int> ansPath;
int k;
void dfs(int cur, vector<int> path, int w){
if(flag) return;
vis[cur] = true;
if(w > m) return;
if(w == m){
flag = true;
ansPath = path;
return;
}
for(int i = cur+1; i<=k; i++){
if(!vis[i]){
path.push_back(coin[i]);
dfs(i, path, w+coin[i]);
vis[i] = false;
path.pop_back();
}
}
}
int main(){
scanf("%d%d", &n, &m);
long sum = 0;
for(int i = 1; i<=n; i++){
scanf("%d", &coin[i]);
sum += coin[i];
}
if(sum < m) printf("No Solution");
else {
sort(coin+1, coin+n+1);
k = n;
for(int i = 1; i<=n; i++)
if(coin[i]>=m){
k = i;
break;
}
dfs(0, ansPath, 0);
if(flag){
printf("%d", ansPath[0]);
for(int i = 1; i<ansPath.size(); i++)
printf(" %d", ansPath[i]);
}
else printf("No Solution");
}
return 0;
}
使用的硬币数量最少
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n,m;
cin>>n>>m;
vector<int>coin(n+1);
for(int i=1;i<=n;++i)
scanf("%d",&coin[i]);
sort(coin.begin()+1,coin.end());
vector<int>dp(m+1,0);
dp[0]=1;
vector<vector<int>>compose(m+1);
for(int i=1;i<=n;++i){
for(int j=m;j>=coin[i];--j){
if(dp[j-coin[i]]==1&&(compose[j-coin[i]].size()+1<compose[j].size()||compose[j].size()==0)){
compose[j]=compose[j-coin[i]];
compose[j].push_back(coin[i]);
}
dp[j]=dp[j]||dp[j-coin[i]];
}
}
if(dp[m]==1){
for(int i=0;i<compose[m].size();++i){
if(i==0) printf("%d",compose[m][i]);
else printf(" %d",compose[m][i]);
}
}else{
printf("No Solution");
}
return 0;
}
|