深度优先搜索 DFS(Depath First Search, DFS)
深度优先搜索是一种枚举所有完整路径以遍历所有情况的搜索方法。(不撞南墙不回头)
DFS一般用递归来实现,其伪代码思路过程一般如下:
void DFS(必要的参数){
if (符和遍历到一条完整路径的尾部){
更新某个全局变量的值
}
if (跳出循环的临界条件){
return;
}
对所有可能出现的情况进行递归
}
常见题型1:

代码实现:
#include <stdio.h>
const int maxn = ;
int n, V, maxVal = ; // 物品减数, 背包容量,最大价值maxValue
int w[];
int c[];
int ans = ; // 最大价值 // dfs, index是物品编号,nowW是当前所收纳的物品容量,nowC是当前所收纳的物品的总价值
void dfs(int index, int nowW, int nowC){
if (index == n){
return;
}
dfs(index + , nowW, nowC); // 不选第index件商品
if (nowW + w[index] <= V){ // 选第index件商品,但是先判断容量是否超限
if (nowC + c[index] > ans){
ans = nowC + c[index]; // 更新最大价值
}
dfs(index + , nowW + w[index], nowC + c[index]);
}
} int main()
{
scanf("%d %d", &n, &V);
for (int i = ; i < n; i++){
scanf("%d", &w[i]); // 每件物品的重量
}
for (int i = ; i < n; i++){
scanf("%d", &c[i]); // 每件物品的价值
} dfs(, , );
printf("%d\n", ans); return ;
}
常见题型二:
枚举从N 个整数找那个选择K个数(有时这个数可能可以重复)的所有方案(有时要打印这个方案的序列)

代码实现:
#include <stdio.h>
#include <vector>
using namespace std; const int maxn = ;
// 从包含n个数的序列A中选k个数使得和为x, 最大平方和为maxSumSqu;
int n, k, sum, maxSumSqu = -, A[maxn];
vector<int> temp, ans; // temp存放临时方案,ans存放平方和最大的方案 void DFS(int index, int nowK, int nowSum, int nowSumSqu){
if (nowK == k && nowSum == sum){
if (nowSumSqu > maxSumSqu){
maxSumSqu = nowSumSqu;
ans = temp;
}
return;
}
// 如果已经处理完n个数,或者选择了超过k个数,或者和超过x
if (index == n && nowK > k && nowSum > sum){
return;
} // 选这个数
temp.push_back(A[index]);
DFS(index + , nowK + , nowSum + A[index], nowSumSqu + A[index] * A[index]); // 不选这个数
// 先把刚加到temp中的数据去掉
temp.pop_back();
DFS(index + , nowK, nowSum, nowSumSqu);
}
如果选出的k个数可以重复,那么只需将上面“选这个数的 index + 1 改成 index 即可”
将
DFS(index + , nowK + , nowSum + A[index], nowSumSqu + A[index] * A[index]);
改成
DFS(index, nowK + , nowSum + A[index], nowSumSqu + A[index] * A[index]);
DFS题型实战:
The K−P factorization of a positive integer N is to write N as the sum of the P-th power of K positive integers. You are supposed to write a program to find the K−P factorization of N for any positive integers N, K and P.
Input Specification:
Each input file contains one test case which gives in a line the three positive integers N (≤400), K (≤N) and P (1<P≤7). The numbers in a line are separated by a space.
Output Specification:
For each case, if the solution exists, output in the format:
N = n[1]^P + ... n[K]^P
where n[i] (i = 1, ..., K) is the i-th factor. All the factors must be printed in non-increasing order.
Note: the solution may not be unique. For example, the 5-2 factorization of 169 has 9 solutions, such as 122+42+22+22+12, or 112+62+22+22+22, or more. You must output the one with the maximum sum of the factors. If there is a tie, the largest factor sequence must be chosen -- sequence { a1,a2,⋯,aK } is said to be larger than { b1,b2,⋯,bK } if there exists 1≤L≤K such that ai=bi for i<L and aL>bL.
If there is no solution, simple output Impossible.
Sample Input 1:
169 5 2
Sample Output 1:
169 = 6^2 + 6^2 + 6^2 + 6^2 + 5^2
Sample Input 2:
169 167 3
Sample Output 2:
Impossible
代码实现:
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <math.h>
using namespace std; // 从1 - 20中选出k个数,数可重复,使得这些数的p次方的和刚好等于n, 求这些序列中和最大的那个序列 int A[];
int flag = ;
int n, k, p, maxSum = -;
vector<int> ans, temp, fac; // ans 存放最终序列, temp存放临时序列 // 快速幂
int power(int i){
/*if (p == 1 )
return i;
if ((p & 1) != 0)
return i * power(i, p - 1);
else
{
int temp = power(i, p / 2);
return temp * temp;
}*/ int ans = ;
for (int j = ; j < p; j++){
ans *= i;
}
return ans;
} // 求出所有不大于n的p次幂
void init(){
int i = , temp = ;
while (temp <= n){
fac.push_back(temp);
temp = power(++i);
}
} // DFS
void DFS(int index, int nowK, int sum, int squSum){
// 临界条件
if (squSum == n && nowK == k){
if (sum > maxSum){
maxSum = sum;
ans = temp;
} return;
} if (sum > n || nowK > k){
return;
} if (index >= ){
// 遍历所有可能的情况
// 选当前数
temp.push_back(index);
DFS(index, nowK + , sum + index, squSum + fac[index]); // 不选当前数
temp.pop_back();
DFS(index - , nowK, sum, squSum); }
} int main()
{
// 读取输入
// freopen("in.txt", "r", stdin);
scanf("%d %d %d", &n, &k, &p); // 初始化fac数组
init(); // DFS寻找最合适的序列
DFS(fac.size() - , , , ); // 输出
// 如果ans的size大于1则说明有结果
if (maxSum != -){
// 排序
printf("%d = %d^%d", n, ans[], p);
for (int i = ; i < ans.size(); i++){
printf(" + %d^%d", ans[i], p);
}
}else
printf("Impossible"); // fclose(stdin);
return ;
}
这个实战题主要就是要先把 所有不超过 N 的 i ^p都算出来,要不然会超时
深度优先搜索 DFS(Depath First Search, DFS)的更多相关文章
- 深度优先搜索(Depth First Search)
Date:2019-07-01 15:31:11 通俗点理解就是不撞南墙不回头的那种,用栈来实现 算法实现 /* 题目描述: 有n件物品,每件物品的重量为w[i],价值为c[i].现在需要选出若干件物 ...
- [算法入门]——深度优先搜索(DFS)
深度优先搜索(DFS) 深度优先搜索叫DFS(Depth First Search).OK,那么什么是深度优先搜索呢?_? 样例: 举个例子,你在一个方格网络中,可以简单理解为我们的地图,要从A点到B ...
- 【数据结构与算法Python版学习笔记】图——骑士周游问题 深度优先搜索
骑士周游问题 概念 在一个国际象棋棋盘上, 一个棋子"马"(骑士) , 按照"马走日"的规则, 从一个格子出发, 要走遍所有棋盘格恰好一次.把一个这样的走棋序列 ...
- 深度优先搜索(Depth-First-Search)精髓
引例:迷宫问题 首先我们来想象一只老鼠,在一座不见天日的迷宫内,老鼠在入口处进去,要从出口出来.那老鼠会怎么走?当然可以是这样的:老鼠如果遇到直路,就一直往前走,如果遇到分叉路口,就任意选择其中的一条 ...
- [LeetCode OJ] Word Search 深度优先搜索DFS
Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ...
- [MIT6.006] 14. Depth-First Search (DFS), Topological Sort 深度优先搜索,拓扑排序
一.深度优先搜索 它的定义是:递归探索图,必要时要回溯,同时避免重复. 关于深度优先搜索的伪代码如下: 左边DFS-Visit(V, Adj.s)是只实现visit所有连接某个特定点(例如s)的其他点 ...
- 图的遍历之深度优先搜索(DFS)
深度优先搜索(depth-first search)是对先序遍历(preorder traversal)的推广.”深度优先搜索“,顾名思义就是尽可能深的搜索一个图.想象你是身处一个迷宫的入口,迷宫中的 ...
- 『ACM C++』HDU杭电OJ | 1416 - Gizilch (DFS - 深度优先搜索入门)
从周三课开始总算轻松了点,下午能在宿舍研究点题目啥的打一打,还好,刚开学的课程还算跟得上,刚开学的这些课程也是复习以前学过的知识,下半学期也不敢太划水了,被各种人寄予厚望之后瑟瑟发抖,只能努力前行了~ ...
- DFS(一):深度优先搜索的基本思想
采用搜索算法解决问题时,需要构造一个表明状态特征和不同状态之间关系的数据结构,这种数据结构称为结点.不同的问题需要用不同的数据结构描述. 根据搜索问题所给定的条件,从一个结点出发,可以生成一个或多个新 ...
随机推荐
- Badusb 简易制作
Badusb easy_make 0x00 basic knowledge and equip arduino IDE download address: https://www.arduino.cc ...
- MySQL 8 拷贝MySQL数据库到另一台机器
通过mysqldump生成包含SQL语句的文件,然后将其应用到目标机器的mysql客户端程序. mysqldump --help 可以获取mysqldump选项以及用法. 如果源服务器上启用了GTID ...
- 有多少人在面试时,被Java 如何线程间通讯,问哭了?
正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及到的知识点: thread.join(), object. ...
- Java多线程之互斥锁Syncharnized
public class Bank { private int money; private String name; public Bank(String name, int money) { th ...
- Luogu2040 | 打开所有的灯 (广搜+状压)
题目背景 pmshz在玩一个益(ruo)智(zhi)的小游戏,目的是打开九盏灯所有的灯,这样的游戏难倒了pmshz... 题目描述 这个灯很奇(fan)怪(ren),点一下就会将这个灯和其周围四盏灯的 ...
- CF #618 div.2
序 闲来无事,打场CF,本人蒟蒻,考场A了前三道,第四有解答 正文 T1 Non-zero 是道水题.... 给你一个序列a.要求你输出最少的操作次数使这个序列的累和与累乘都不为0: 一次操作指给\( ...
- Picture POJ - 1177 线段树+离散化+扫描线 求交叉图像周长
参考 https://www.cnblogs.com/null00/archive/2012/04/22/2464876.html #include <stdio.h> #include ...
- VISIO 的一些技巧
1.复制绘图 如果格式改变,在“设计”选项卡里将“将主题运用于新建的形状”前面的√去掉
- JavaScript-跨浏览器事件处理程序(EventUtil)
事件操作对象: var EventUtil= { //添加事件 addHandler: function (element, type, handler) { if (element.addEvent ...
- Linux系统下的CPU、内存、IO、网络的压力测试
本文转载自:小豆芽博客 一.对CPU进行简单测试: 1.通过bc命令计算特别函数 例:计算圆周率 echo "scale=5000; 4*a(1)" | bc -l -q MATH ...