深度优先搜索是一种枚举所有完整路径以遍历所有情况的搜索方法。(不撞南墙不回头)

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题型实战:

          1103 Integer Factorization (30分)

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 12​2​​+4​2​​+2​2​​+2​2​​+1​2​​, or 11​2​​+6​2​​+2​2​​+2​2​​+2​2​​, 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 { a​1​​,a​2​​,⋯,a​K​​ } is said to be larger than { b​1​​,b​2​​,⋯,b​K​​ } if there exists 1≤L≤K such that a​i​​=b​i​​ for i<L and a​L​​>b​L​​.

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)的更多相关文章

  1. 深度优先搜索(Depth First Search)

    Date:2019-07-01 15:31:11 通俗点理解就是不撞南墙不回头的那种,用栈来实现 算法实现 /* 题目描述: 有n件物品,每件物品的重量为w[i],价值为c[i].现在需要选出若干件物 ...

  2. [算法入门]——深度优先搜索(DFS)

    深度优先搜索(DFS) 深度优先搜索叫DFS(Depth First Search).OK,那么什么是深度优先搜索呢?_? 样例: 举个例子,你在一个方格网络中,可以简单理解为我们的地图,要从A点到B ...

  3. 【数据结构与算法Python版学习笔记】图——骑士周游问题 深度优先搜索

    骑士周游问题 概念 在一个国际象棋棋盘上, 一个棋子"马"(骑士) , 按照"马走日"的规则, 从一个格子出发, 要走遍所有棋盘格恰好一次.把一个这样的走棋序列 ...

  4. 深度优先搜索(Depth-First-Search)精髓

    引例:迷宫问题 首先我们来想象一只老鼠,在一座不见天日的迷宫内,老鼠在入口处进去,要从出口出来.那老鼠会怎么走?当然可以是这样的:老鼠如果遇到直路,就一直往前走,如果遇到分叉路口,就任意选择其中的一条 ...

  5. [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 ...

  6. [MIT6.006] 14. Depth-First Search (DFS), Topological Sort 深度优先搜索,拓扑排序

    一.深度优先搜索 它的定义是:递归探索图,必要时要回溯,同时避免重复. 关于深度优先搜索的伪代码如下: 左边DFS-Visit(V, Adj.s)是只实现visit所有连接某个特定点(例如s)的其他点 ...

  7. 图的遍历之深度优先搜索(DFS)

    深度优先搜索(depth-first search)是对先序遍历(preorder traversal)的推广.”深度优先搜索“,顾名思义就是尽可能深的搜索一个图.想象你是身处一个迷宫的入口,迷宫中的 ...

  8. 『ACM C++』HDU杭电OJ | 1416 - Gizilch (DFS - 深度优先搜索入门)

    从周三课开始总算轻松了点,下午能在宿舍研究点题目啥的打一打,还好,刚开学的课程还算跟得上,刚开学的这些课程也是复习以前学过的知识,下半学期也不敢太划水了,被各种人寄予厚望之后瑟瑟发抖,只能努力前行了~ ...

  9. DFS(一):深度优先搜索的基本思想

    采用搜索算法解决问题时,需要构造一个表明状态特征和不同状态之间关系的数据结构,这种数据结构称为结点.不同的问题需要用不同的数据结构描述. 根据搜索问题所给定的条件,从一个结点出发,可以生成一个或多个新 ...

随机推荐

  1. Notes writer Pro

    Notes writer Pro pen钢笔和Pencil铅笔发现没啥区别 笔记软件使用说明书: https://www.lanzous.com/i777i3c

  2. css基础-定位+网页布局案例

    position:static 忽略top/bottom/left/right或者z-index position:relative 设置相对定位的元素不会脱离文档流 position:fixed 不 ...

  3. MySQL概述及入门(三)

    MySql概述及入门(三) MySQL性能优化 主要优化安全和性能方面 安全方面 : 数据可持续性 性能方面 : 数据的高性能访问 性能优化——慢查询 在MySQL数据库中有一个慢查询日志功能,去获取 ...

  4. P2256 一中校运会之百米跑

    ----------------------- 题目链接:MIKU --------------------- 我现在发现找BUG的最好方法————喝水 喝一次找一个,喝两次A道题 --------- ...

  5. SpringBoot从1.5.1→2.2.4项目加包扫雷三:org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter已过时

    @Configuration@Slf4j@PropertySource({"classpath:/config.properties"})public class MyWebApp ...

  6. Linux系统之网络相关的命令

    Linux系统之网络相关的命令 网络概述 网络:通过通信介质和通信设备 将分布不同地点的两台或多台计算机,经过相应的程序实现通信switch 交换机router 路由器网络的功能:数据通信:利用网络传 ...

  7. 硬核干货 | C++后台开发学习路线

    2020秋招提前批 C/C++相关开发 拿到腾讯.华为等offer 学习路线及时间安排 推荐时间为4个月,包括四部分:语言,计算机基础知识,项目基础知识,项目实践. 语言 推荐学习1个月 学习方针:视 ...

  8. C#中System.ServiceProgress报错

    场景 在C#中检索本地计算机所有服务时,使用 System.ServiceProcess.ServiceController[] services = System.ServiceProcess.Se ...

  9. 886. 求组合数 II(模板)

    数据范围较大, a,b都是1e5 直接根据公式预处理  1/i就是求i的逆元(逆元求法:mod为质数,逆元就是 i^(mod-2)%mod ) O(N*logN) import java.util.S ...

  10. JS中axios使用注意点

    今天遇到这样一个问题,前端会同时弹出成功和失败的两个提示框,由于不是本人操作,也没有怀疑是前端代码的问题,就索性根据后端的日志作为分析依据,开始个人以为是后端接口上班了两次结果,一个是成功,另外一个是 ...