Depth-First Search
深度搜索和宽度搜索对立,宽度搜索是横向搜索(队列实现),而深度搜索是纵向搜索(递归实现);
看下面这个例子:
现在需要驾车穿越一片沙漠,总的行驶路程为L。小胖的吉普装满油能行驶X距离,同时其后备箱最多能放下四桶油。在起点有N种汽油,每种汽油都有无限桶,一桶能行驶距离Ai。现在小胖想知道:能不能恰好带四桶油,再加上出发前装满的油,使得恰好能行驶L距离。
两个 恰好 使得这道题的难度增加;
如何才能做到恰好? 动态规划 还是 搜索?
先看看搜索行不行
限制条件是:“恰好四桶油”,“恰好行驶距离为L”
那就一个一个的试试,深搜一把试试看
bool flag = false ;
void dfs( int tong , int s ) {
if(tong > 4 || s > L)
return ;
if(tong == 4 && s == L) {
flag = true ;
return ;
}
for(int i = 1 ; i <= n ; i++ ) // n 为汽油种类
for(int j = 1 ; j <= 4 ; j++)
dfs(tong + j , s + a[i] * j ) ;
}
如果能够找到 flag 就为 true ;
判断 flag 即可得出结果;
具体实现代码如下:
#include<iostream>
#include<string.h>
#include<string>
#include<algorithm>
using namespace std ; int a[1005] ; int L , X , N ; int ans ; void dfs(int a1 , int sum) {
if(a1 > 4 || sum > L - X)
return ;
if(a1 == 4 && sum == L - X) {
ans = 1 ;
return ;
}
for(int i = 1 ; i <= N ; i++)
for(int j = 1 ; j <= 4 ; j++)
dfs(a1+j , sum + a[i] * j ) ;
} int main() {
int n ;
cin >> n ;
while(n--) {
cin >> L >> X >> N ;
memset(a,0,sizeof(a[0])) ;
for(int i = 1 ; i <= N ; i++)
cin >> a[i] ;
sort(a+1,a+1+n) ;
ans = 0 ;
dfs(0,0) ;
if(ans)
cout << "Yes" << endl ;
else
cout << "No" << endl ;
}
return 0 ;
}
很高兴总算找到答案了,但是不要忘了这个数据可能会很大,如果还用这个方法肯定会超时,如果一个算法速度达不到,这个算法是没有多大意义的。
那我们下面应该想想能不能用对程序进行优化,看到上面是不是有很多地方都是重复计算了,一般可以用多消耗一些内存换取程序运行的时间;
观察发现,当带四桶相同的油,多算了好多,既然是深度搜索,应该一直往深度探索,所以以上程序可修改为:
#include<iostream>
#include<string.h>
#include<string>
#include<algorithm>
using namespace std ; int a[1005] ; int L , X , N ; int ans ; void dfs(int i ,int a1 , int sum) {
if(a1 > 4 || sum > L - X)
return ;
if(a1 == 4 && sum == L - X) {
ans = 1 ;
return ;
}
for( ; i <= N ; i++)
for(int j = 1 ; j <= 4 ; j++)
dfs(i+1,a1+j , sum + a[i] * j ) ;
} int main() {
int n ;
cin >> n ;
while(n--) {
cin >> L >> X >> N ;
memset(a,0,sizeof(a[0])) ;
for(int i = 1 ; i <= N ; i++)
cin >> a[i] ;
sort(a+1,a+1+n) ;
ans = 0 ;
dfs(1,0,0) ;
if(ans)
cout << "Yes" << endl ;
else
cout << "No" << endl ;
}
return 0 ;
}
就算如此优化,还是避免不了超时的结果,那还应该如何优化才能达到想要的结果呢,结果发现,还存在可以优化的地方,如果一桶汽油就可以跑完全程,那样的汽油就应该抛弃,通过先前对汽油种类排序,最后留下来的都是一桶跑不完全程的,当全程不能够分成四份时,那么同一种汽油最多取三桶;
通过分析再次对上面程序就行优化得到下面程序:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[1002];
int l,x,n,m;
int flag;
void dfs(int i,int count,int sum)
{
int j;
if(count>4||sum>l||flag)
return;
if(count==4&&sum==l)
{
flag=1;
return ;
}
for(;i<n;i++)
for(j=1;j<=m;j++)
dfs(i+1,count+j,sum+j*a[i]);
}
int main()
{
int t;
int i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&l,&x,&n);
l=l-x;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
for(i=0;i<n;i++)
if(a[i]>=l) //若第a[i]种汽油,一桶的行驶路程不小于l-x,后面的搜索情况不能满足题意,直接舍弃后面的数据
{
n=i;
break;
}
m=4;
if(l%4!=0) //若l-x不能被4整除,每种汽油最多带3桶,可能满足题意
m=3;
flag=0;
dfs(0,0,0);
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
下面介绍一种用动态规划解答方案:
用 dp[ i ][ j ] 代表 带 i 桶汽油,恰好能行驶 j 公里,如果 dp[ 4 ][ L ] = true 则代表存在 ;
#include<iostream>
#include<string>
#include<string.h>
using namespace std ;
int main() {
int n ;
cin >> n ;
while(n--) {
bool dp[6][1005] ; // dp[i][j] 带 i 桶汽油,恰好能行驶 j 公里
memset(dp,false,sizeof(dp)) ;
int L , X , N ;
cin >> L >> X >> N ;
int a[1005];
for(int ii = 1 ; ii <= N ; ii++)
cin >> a[ii] ;
L = L - X ;
dp[0][0] = true ; // 带 0 桶汽油 , 恰好行驶 0 公里
for(int i = 0 ; i <= L ; i++) // 控制条件有两个时,主要判断哪个在前,哪个在后
for(int j = 0 ; j <= 4 ; j++) {
if(dp[j][i])
for(int k = 1 ; k <= N ; k++) {
if(i + a[k] <= L )
dp[j+1][i+a[k]] = true ; // 为动态变量赋值
}
}
if(dp[4][L])
cout << "Yes" << endl ;
else
cout << "No" << endl ;
}
return 0 ;
}
Depth-First Search的更多相关文章
- [算法&数据结构]深度优先搜索(Depth First Search)
深度优先 搜索(DFS, Depth First Search) 从一个顶点v出发,首先将v标记为已遍历的顶点,然后选择一个邻接于v的尚未遍历的顶点u,如果u不存在,本次搜素终止.如果u存在,那么从u ...
- [Algorithm] Write a Depth First Search Algorithm for Graphs in JavaScript
Depth first search is a graph search algorithm that starts at one node and uses recursion to travel ...
- Non recursive Depth first search
深度优先非递归实现算法: 1 递归算法: //初始化相关数据结构 DFS(G) ------------------------------------------------------------ ...
- Recursive Depth first search graph(adj matrix)
1 深度优先遍历邻接矩阵 1 邻接矩阵初始化 2 访问数组初始化 3 深度优先遍历邻接矩阵图 算法如下: bool MGraph[128][128]; bool visit[128]; int vex ...
- 幸运的袋子(深度优先遍历(Depth First Search,DFS))
题目描述 一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的).如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积. 例如:如果袋子里面的球的号码是{1, 1, 2 ...
- 深度优先搜索(Depth First Search)
Date:2019-07-01 15:31:11 通俗点理解就是不撞南墙不回头的那种,用栈来实现 算法实现 /* 题目描述: 有n件物品,每件物品的重量为w[i],价值为c[i].现在需要选出若干件物 ...
- Add Digits, Maximum Depth of BinaryTree, Search for a Range, Single Number,Find the Difference
最近做的题记录下. 258. Add Digits Given a non-negative integer num, repeatedly add all its digits until the ...
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- [LeetCode] Maximum Depth of Binary Tree 二叉树的最大深度
Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...
- [LeetCode] 104. Maximum Depth of Binary Tree 二叉树的最大深度
Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...
随机推荐
- Cppcheck软件使用
一款开源源码检测工具.简单易用. 官网网址:http://cppcheck.sourceforge.net/ 软件可直接官网下载. [plain] view plaincopy Features Ou ...
- 面向对象程序设计-C++_课时11new & delete
Dynamic memory allocation new new int; new Stash; new int[10]; new返回这个对象的指针 delete delete p; delete[ ...
- CouldnotcreateServerSocketonaddress0.0.0.0/0.0.0.0:9083
错误记录 安装的时候遇到了如下错误 Exception in thread "main" org.apache.thrift.transport.TTransportExcepti ...
- ios webview 加载含有中文的URL网页显示白屏
1. ios中的webview加载的URL不可以含有中文,解决办法说将中文字符转码, 如下: - (NSString *)URLEncodeString { NSCharacterSet *set = ...
- uva 639 Don't Get Rooked 变形N皇后问题 暴力回溯
题目:跟N皇后问题一样,不考虑对角冲突,但考虑墙的存在,只要中间有墙就不会冲突. N皇后一行只能放一个,而这题不行,所以用全图暴力放棋,回溯dfs即可,题目最多就到4*4,范围很小. 刚开始考虑放一个 ...
- JS判断是否安装flash player及当前版本
function flashChecker() { var hasFlash = 0; //是否安装了flash var flashVersion = 0; //flash版本 if(document ...
- Neo4j数据库简单
作为世界上先进的地图数据库,Neo4j如今,公司已成为许多互联网的首选.Neo4j它是基于java开源地图数据库开发,另外一个NoSQL数据库.Neo4j在保证对数据关系的良好刻画的同一时候.还支持传 ...
- 发现一个名为“Douyu”的国人项目
刚刚在javaeye看到一个名为Douyu的国人项目,认为搞下去未来可能非常有意思,放到blog上做个标记. ——————下面是转载的作者原文——————— 原文地址例如以下:http://zhh20 ...
- 关于Installation error: INSTALL_FAILED_MISSING_SHARED_LIBRARY
google 给的android的例子里,有用到google APIs,新版本的ADT默认只有Android的SDK,如果运行平台与目标平台不一致会报:Installation error: INST ...
- JTable只要一双击就进入编辑状态,禁止的方法实现
我用JTable做了一个表格,表格内容只供查看和选择,可每次只要一双击,就进入编辑状态,可是现在我不需要当双击的时候修改表格的内容.这时候需要重载isCellEditable方法. 下面是我的实现的代 ...