我大概花了一周时间才搞懂dfs(小懂而已),主要因为我连函数都不用(能不用则不用),所以对dfs理解的有些慢(龟速),所以能够优化结构的,或者什么高级点的东西(虽说函数只是基础),还是应该多去练习。
通俗点讲,我觉得DFS就是函数里面用函数。
举个题做例子:
(我当时就是从这个题得到的突破)
Farmer John最近为奶牛们的图书馆添置了一个巨大的书架,尽管它是如此的大,但它还是几乎瞬间就被各种各样的书塞满了。现在,只有书架的顶上还留有一点空间。
所有N(1 <= N <= 20)头奶牛都有一个确定的身高H_i(1 <= H_i <= 1,000,000 - 好高的奶牛>_<)。设所有奶牛身高的和为S。书架的高度为B,并且保证1 <= B <= S。 为了够到比最高的那头奶牛还要高的书架顶,奶牛们不得不象演杂技一般,一头站在另一头的背上,叠成一座“奶牛塔”。当然,这个塔的高度,就是塔中所有奶牛的身高之和。
为了往书架顶上放东西,所有奶牛的身高和必须不小于书架的高度。
塔叠得越高便越不稳定,于是奶牛们希望找到一种方案,使得叠出的塔在高度不小于书架高度的情况下,高度尽可能小。你也可以猜到你的任务了:写一个程序,计算奶牛们叠成的塔在满足要求的情况下,最少要比书架高多少。
输入格式 第1行: 2个用空格隔开的整数:N 和 B 第2…N+1行: 第i+1行是1个整数:H_i
输出格式 第1行: 输出1个非负整数,即奶牛们叠成的塔最少比书架高的高度_
5 16 3 1 3 5 6
1
我们选用奶牛1、3、4、5叠成塔,她们的总高度为3 + 3 + 5 + 6 = 17。任何方案都无法叠出高度为16的塔,于是答案为1。
数据规模与约定
时间限制:1s
空间限制:256MB
这就需要搞个递归,在递归里枚举每头牛,分出两种情况:这头牛取还是不取。 这里的函数首先需要两个变量:第几头牛,高度。 编不下去了, 放代码
#include <bits/stdc++.h> using namespace std; int k,da=999999,ans,h,p;//用da来记录高于书架的最低高度 int a[10086]; void sj(int m,int n) { if(n>=h&&da>n) da=n;//如果高度高于书架且低于其他方法,更新da if(m>k) return; //递归中很重要的一点就是找到边界,不然无限循环 sj(m+1,n); //这头牛不往上摞 sj(m+1,n+a[m]); //这头牛往上摞 } int main() { cin>>k>>h; for(int i=1;i<=k;i++) { cin>>a[i]; //第i头牛的高度 } sj(0,0); //一开始的时候用了0头牛,高度为0 cout<<da-h; //输出高度差 return 0; }有时候如果输不出东西,要检查边界是否设置得当
有人(也可能只有我)会怀疑,递归中的
void sj(int m,int n)在其中多次使用,是否会相互干扰。
看图说话。 可以理解为倒二叉树 把最左的一个枝干砍掉们不会影响其他几根枝干。 而在return后,会继续运行其他树杈。