学习目标:
深度优先搜索
学习内容:
常见dfs问题:给定一个序列,枚举所有子列(不一定连续),选择最优的子序列
例如:
给定N个整数(可能为负数),从中选择K个数,使得这K个数之和恰好等于一个给定的整数X;如果有多个方案,选择它们中元素平方和最大的一个。
深搜方案:
岔路口:选择或是不选择
死胡同:已经对N个整数进行处理
#include <bits/stdc++.h>
using namespace std;
int num[20], k, x, max_sum_square = 0, n;
vector<int> temp, ans;
void dfs(int index, int nowk, int sum, int sum_square) {
if (nowk == k && sum == x) {
if (sum_square > max_sum_square) {
max_sum_square = sum_square;
ans = temp;
}
}
if (nowk == k || sum > x || index == n)
return;
temp.push_back(num[index]);
dfs(index + 1, nowk + 1, sum + num[index], sum_square + num[index] * num[index]);
temp.pop_back();
dfs(index + 1, nowk, sum, sum_square);
}
int main () {
cin >> n >> k >> x;
for (int i = 0; i < n; i++) {
cin >> num[i];
}
dfs(0, 0, 0, 0);
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << " ";
}
input
4 2 6
2 3 3 4
output
2 4
例如:
给定N个整数(可能为负数),从中选择K个数***(每个数都可以多次选择)***,使得这K个数之和恰好等于一个给定的整数X;如果有多个方案,选择它们中元素平方和最大的一个。
深搜方案
岔路口:一直选这个数或选下一个数
死胡同:已经对N个数处理
#include <bits/stdc++.h>
using namespace std;
int num[20], k, x, max_sum_square = 0, n;
vector<int> temp, ans;
void dfs(int index, int nowk, int sum, int sum_square) {
if (nowk == k && sum == x) {
if (sum_square > max_sum_square) {
max_sum_square = sum_square;
ans = temp;
}
}
if (nowk == k || sum > x || index == n)
return;
temp.push_back(num[index]);
dfs(index, nowk + 1, sum + num[index], sum_square + num[index] * num[index]); //一直选,index不加一。
temp.pop_back();
dfs(index + 1, nowk, sum, sum_square); //不选
}
int main () {
cin >> n >> k >> x;
for (int i = 0; i < n; i++) {
cin >> num[i];
}
dfs(0, 0, 0, 0);
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << " ";
}