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

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. Badusb 简易制作

    Badusb easy_make 0x00 basic knowledge and equip arduino IDE download address: https://www.arduino.cc ...

  2. MySQL 8 拷贝MySQL数据库到另一台机器

    通过mysqldump生成包含SQL语句的文件,然后将其应用到目标机器的mysql客户端程序. mysqldump --help 可以获取mysqldump选项以及用法. 如果源服务器上启用了GTID ...

  3. 有多少人在面试时,被Java 如何线程间通讯,问哭了?

    正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及到的知识点: thread.join(), object. ...

  4. Java多线程之互斥锁Syncharnized

    public class Bank { private int money; private String name; public Bank(String name, int money) { th ...

  5. Luogu2040 | 打开所有的灯 (广搜+状压)

    题目背景 pmshz在玩一个益(ruo)智(zhi)的小游戏,目的是打开九盏灯所有的灯,这样的游戏难倒了pmshz... 题目描述 这个灯很奇(fan)怪(ren),点一下就会将这个灯和其周围四盏灯的 ...

  6. CF #618 div.2

    序 闲来无事,打场CF,本人蒟蒻,考场A了前三道,第四有解答 正文 T1 Non-zero 是道水题.... 给你一个序列a.要求你输出最少的操作次数使这个序列的累和与累乘都不为0: 一次操作指给\( ...

  7. Picture POJ - 1177 线段树+离散化+扫描线 求交叉图像周长

    参考  https://www.cnblogs.com/null00/archive/2012/04/22/2464876.html #include <stdio.h> #include ...

  8. VISIO 的一些技巧

    1.复制绘图 如果格式改变,在“设计”选项卡里将“将主题运用于新建的形状”前面的√去掉

  9. JavaScript-跨浏览器事件处理程序(EventUtil)

    事件操作对象: var EventUtil= { //添加事件 addHandler: function (element, type, handler) { if (element.addEvent ...

  10. Linux系统下的CPU、内存、IO、网络的压力测试

    本文转载自:小豆芽博客 一.对CPU进行简单测试: 1.通过bc命令计算特别函数 例:计算圆周率 echo "scale=5000; 4*a(1)" | bc -l -q MATH ...