题目描述
简言之,给定一堆一定数值的硬币,问是否能凑出给定的面额?
典型的组合优化问题,然而我实在看不懂背包的解法,无奈暴搜+剪枝
重返天梯-L3-001 凑零钱 (30 分) (dfs搜索)
C++(dfs + 后缀和 + 剪枝)
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e4 + 10;
int n, m;
int w[N], s[N];
bool st[N];
bool flag = false;
void dfs(int u, int change) {
if (flag || change + s[u] < m) return;
if (u > n || change >= m) {
if (change == m) {
bool first = false; // 保证输出格式正确
for (int i = 0; i < n; i++) {
if (st[i]) {
if (!first) printf("%d", w[i]), first = true;
else printf(" %d", w[i]);
}
}
flag = true;
}
return;
}
st[u] = true;
dfs(u+1, change + w[u]);
st[u] = false;
dfs(u+1, change);
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) scanf("%d", &w[i]);
sort(w, w + n);
// 计算后缀和,否则会超时
s[n-1] = w[n-1];
for (int i = n-2; i >= 0; i--) s[i] = s[i+1] + w[i];
dfs(0, 0);
if (!flag) puts("No Solution");
return 0;
}