DFS深度搜索算法实现深度探究解析-以POJ 1040为例

本人开园第一天,打算主要发表算法、编程及技术面试题等相关内容,还望各大牛多多指教!

DFS深度搜索算法实现深度探究解析-以POJ 1040为例

 

#include <iostream>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define maxm 23
#define maxn 8
int cap, n, m;
int ans;
int ocount;
int down[maxn];
struct Order{    
	int s, e, p;
}order[maxm];

int max(int a,int b){
	return a>b?a:b;
}
bool operator < (const Order &a, const Order &b){
    if (a.s == b.s)        
		return a.e < b.e;    
	return a.s < b.s;
}

void dfs(int i, int p, int money){   
	if (i == m){      
		ans = max(ans, money);      
		return;    
	} 
	if (i > 0)        
		for (int j = order[i - 1].s + 1; j <= order[i].s; j++)            
			p -= down[j]; 
	if (p + order[i].p <= cap) {       
		down[order[i].e] += order[i].p; //down[i]表示i号车站有多少人下车
		dfs(i + 1, p + order[i].p, money + order[i].p * (order[i].e - order[i].s));
		down[order[i].e] -= order[i].p;
	} 
	dfs(i + 1, p, money);
}

int main(){
	int i;
	while(cin>>cap>>n>>m,cap||n||m){
		for(i=0;i<m;i++){   
			scanf("%d%d%d", &order[i].s, &order[i].e, &order[i].p);        
		}
		sort(order,order+m);
		ans = 0;
		dfs(0,0,0);
		printf("%d\n",ans);
	}
	return 0;
}

 

本题DFS算法实现深度解析:

1、 对order数组排序,使得票的始发站升序排练,当始发站相同时,使得终点站升序排列,这样便于统计每张票的始发站处下车的人数。

2、 DFS递归函数返回有两种情况:其一是i==m时该条路径搜索结束返回结果到原始调用处;其二是执行到DFS末尾返回,也是返回到调用该次DFS函数处。注意区分34行与37行调用DFS函数的不同,开始选择第1、2、3票搜索路径的DFS函数调用情况如下图所示

:

 

第34行的DFS调用是考虑选择第i张票,继续深度搜索;第37行的DFS调用是考虑不选择第i张票(可能由于选第i张票超过了火车容量限制或者是前面的搜索选择完毕回溯)调用的地方不同,自然dfs函数返回的地方也不同。

      通过本题的分析,总结经验如下:

      算法学习最忌讳粗枝大叶,很多看似思想简单的算法实现成代码运行就有很多新的难题,比如深度搜索DFS的实现,有以下关键点:

     1、由于搜索过程高度重复化,一般写成递归函数,DFS函数里面写明返回条件,不同情况下不同的递归调用条件。

     2、 DFS函数的构造一般有一个变量记录当前搜索的位置(如本题中i记录了当前搜索到了第几张票的选择),另外若干变量保存需要一直维护状态变量(如本题中的p记录了当前火车上的人数,money记录了当前选择方案下的总钱数)

    3、 DFS发生回溯的时候,要注意恢复原来状态变量的值(又叫“恢复现场”),比如第35行      down[order[i].e] -=order[i].p; 这里是由于前面考虑选择第i张票的搜索路径已经搜索完毕,那么下面考虑不选择第i张票,恢复下车人数数组down的状态到不选第i张票的情况,在第37行直接去考察第i+1张票的选择情况。

      最后,对于调用及执行情况比较复杂的代码,用好VC等IDE单步调试,观察callback、watch等窗口中函数调用、关键变量值的变化是很重要的研究途径,调试工具要充分利用。有必要学习一下重要的调试技巧,对于加深对程序的理解有好处。

posted @ 2011-12-22 21:32  yangleo  阅读(1069)  评论(0编辑  收藏  举报