最少元素和为 K 的子集选择 - DFS 算法实现及解生成树
最少元素和为 K 的子集选择 - DFS 算法实现及解生成树
给定若干个正整数 a0、a1、...、an-1,从中选出若干数,使它们的和恰好为 k,要求找选择元素个数最少的解。
本文将使用深度优先搜索 (DFS) 算法解决这个问题,并绘制了解生成树,帮助读者理解算法的流程和剪枝策略。
DFS 算法实现
void dfs(vector<int> path, int sum, int start) //求解算法
{
if (sum == k) //找到了一组解
{
if (path.size() < ans.size()) //更新最优解
{
ans = path;
}
return;
}
if (start == n || sum > k || path.size() >= ans.size()) //剪枝
{
return;
}
//不选当前数
dfs(path, sum, start + 1);
//选当前数
path.push_back(a[start]);
dfs(path, sum + a[start], start + 1);
path.pop_back(); //回溯
}
int main()
{
cin >> n >> k;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
sort(a, a + n); //排序
vector<int> path;
dfs(path, 0, 0);
//输出最优解
for (int i = 0; i < ans.size(); i++)
{
cout << ans[i] << ' ';
}
cout << endl;
return 0;
}
解生成树
[这里插入解生成树的图片]
代码说明
dfs(path, sum, start)函数是深度优先搜索的核心函数,它接受三个参数:path: 当前选择的元素集合sum: 当前元素集合的和start: 当前搜索的起始位置
ans: 记录找到的最优解(元素个数最少的解)n: 给定正整数的个数k: 目标和a[i]: 给定的正整数
剪枝策略
sum == k: 如果当前元素集合的和等于k,则找到了一组解,需要更新ans并返回。start == n: 如果当前搜索的起始位置已经超过了最后一个元素,则搜索结束,返回。sum > k: 如果当前元素集合的和已经超过了k,则继续搜索下去也无法找到满足条件的解,因此直接返回。path.size() >= ans.size(): 如果当前选择的元素个数已经大于或等于当前最优解的元素个数,则继续搜索下去也无法找到元素个数更少的解,因此直接返回。
总结
本文介绍了使用深度优先搜索 (DFS) 算法解决给定若干个正整数,从中选出若干数使它们的和恰好为 k,并要求找到选择元素个数最少的解的问题。提供了完整的代码实现,并绘制了解生成树,帮助读者理解算法的流程和剪枝策略。
希望这篇文章能够帮助您更好地理解 DFS 算法及其应用。
原文地址: https://www.cveoy.top/t/topic/oNst 著作权归作者所有。请勿转载和采集!