DFS选数问题
核心要点
- 如何保存最优方案
- 区分能否被多次选择
例一
给定N个整数(可能有负数),从中选择K个数,每个数只可使用一次,使得这K个数之和恰好等于一个给定的整数X;如果有多种方案,选择他们中元素平方和最大的一个。
利用两个数组+一个变量来保存最优方案
- 数组temp存放当前已经选择的整数
- 数组ans存放最优方案
- maxSumSqu存放现有最大平方和
#include <vector>
int n, k, x, maxSumSqu = -1, A[maxn];
vector<int> temp, ans;
void DFS(int index, int nowK, int sum, int sumSqu) {
if (nowK == k && sum == x) {
if (sumSqu > maxSumSqu) {
maxSumSqu = sumSqu;
ans = temp;
}
return;
}
if (index == n || nowK > k || sum > x)
return;
temp.push_back(A[index]);
DFS(index + 1, nowK + 1, sum + A[index], sumSqu + A[index]*A[index]);
temp.pop_back();
DFS(index + 1, nowK, sum, sumSqu);
}
每个数可被选择多次时
//DFS(index + 1, nowK + 1, sum + A[index], sumSqu + A[index]*A[index]);
DFS(index, nowK + 1, sum + A[index], sumSqu + A[index]*A[index]);
在选择了index后,应仍能继续选择index,而不是直接进入index+1的分支。而当不再继续选择index时,则进入另一条分支。
例二
题目来源:PAT A1103
与例一思想相同
扩展
树上dfs保留搜索深度可参考
PAT_A1021题解:The Deepest Root-CSDN博客
BFS分块问题
二维分块
0-1矩阵,相邻的一片1称为一个块,求块数。
#include <cstdio>
#include <queue>
using namespace std;
const int maxn = 100;
struct Node {
int x, y;
} node;
int n, m;
int matrix[maxn][maxn];
bool inq[maxn][maxn] = {false};
int X[4] = {0, 0, 1, -1};
int Y[4] = {1, -1, 0, 0};
bool judge(int x, int y) {
if (x >= n || x < 0 || y >= m || y < 0)
return false;
if (matrix[x][y] == 0 || inq[x][y] == true)
return false;
return true;
}
void bfs(int x, int y) {
queue<Node> q;
node.x = x;
node.y = y;
q.push(node);
inq[x][y] = true;
while (!q.empty()) {
Node top = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int newX = top.x + X[i];
int newY = top.y + Y[i];
if (judge(newX, newY)) {
node.x = newX;
node.y = newY;
q.push(node);
inq[newX][newY] = true;
}
}
}
}
int main() {
scanf("%d%d", &n, &m);
for (int x = 0; x < n; x++) {
for (int y = 0; y < m; y++) {
scanf("%d", &matrix[x][y]);
}
}
int ans = 0;
for (int x = 0; x < n; x++) {
for (int y = 0; y < m; y++) {
if (matrix[x][y] == 1 && inq[x][y] == false) {
ans++;
bfs(x, y);
}
}
}
printf("%d\n", ans);
return 0;
}
- 利用数组来实现坐标方位的切换
三维分块
PAT A1091
区别:
- 对块的体积大小做筛选
- 计数对象不是块数,而是块的体积
- 数组表示三维坐标
有时,BFS也会需要计数遍历的层数。