思路:
开始数组a排好序,搜索是对数组a中每个数有 加/不加 两种状态,先dfs加状态,再dfs不加状态这样就符合搜到的数组递增,当搜出第一个和为m的数组其排序也是所有符合条件数组中最小的直接输出,当已经输出了符合条件的数组后,后面的搜索全部剪枝return掉。
还有个坑点就是所有货币加起来可能不够 m,所以该情况要特判输出No Solution。
代码:
#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)
#define debug(a) cout << "debug : " << (#a) << " = " << a << endl
using namespace std;
typedef long long ll;
typedef pair<int, string> PII;
const int N = 1e4 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int mod = 998244353;
int n, m, sum = 0, cinsum = 0;
vector<int> a, res;
bool flag = true;
void dfs(int x)
{
if (x == n || sum >= m)
{
if (sum == m)
{
flag = false;
for (int i = 0; i < res.size(); i++)
{
if (i != 0)
cout << ' ';
cout << res[i];
}
}
}
else
{
if (!flag)
return;
sum += a[x];
res.push_back(a[x]);
dfs(x + 1);
sum -= a[x];
res.pop_back();
dfs(x + 1);
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
cinsum += x;
a.push_back(x);
}
sort(a.begin(), a.end()); //题意是要按字典序输出货币数额,这里先排了序号,后面比较前就不用排序了
if (cinsum < m)
{
cout << "No Solution" << endl;
return 0;
}
dfs(0);
if (flag)
cout << "No Solution" << endl;
return 0;
}