介绍
英文全称:Deep First Search
枚举所有完整路径来遍历所有情况的搜索方法
return不同情况的介绍
问题描述
在n件物品中,输入其容量与价值。给定容量,求物品的价值之和最大值。
思路
用DFS思想来看,每件物品有选择与不选择两种情况,即岔道;当个数满时,或容量也到达给定的容量时,选择结束,即死路。
过程:当还未到死路时,分别计算不选择该物品与选择该物品时的价值。那么会得到多种不同种到达死路的方法,即多种不同的价值,那么我们就只保存最大的情况
#include <iostream>
using namespace std;
const int maxn=30;
int num=0,volumn=0,maxValue=0;
int volu[maxn],value[maxn];
void DFS(int index,int w,int v){if(index==num){//已放满,达到个数if(w<=volumn&&v>maxValue){maxValue=v;//记录此时价值最大值}return;//返回该函数最开始的位置
}DFS(index+1,w,v);//下标不为index,volu与value值不变DFS(index+1,w+volu[index],v+value[index]);//下标为index,更新容量与价值
}
int main(){cin>>num>>volumn;//输入物品数量与背包容量for(int i=0;i<num;i++)cin>>volu[i];//每件物品的容量for(int i=0;i<num;i++)cin>>value[i];//每件物品的价值DFS(0,0,0);//第0个容量、价值均为0cout<<maxValue<<endl;return 0;
}
提前剪枝改进:
第一种情况是走不选择之后直接走选择,将容量判断留在死路判断(index==n)时,
而走选择其实是有条件的(v<=volumn),所以我们在走第二个岔路之前进行一个容量判断,如果不符合条件就没必要走了,即把就这个分枝剪掉了。
#include <iostream>
using namespace std;
const int maxn=30;
int num=0,volumn=0,maxValue=0;
int volu[maxn],value[maxn];
void DFS(int index,int w,int v){if(index==num){//已放满,达到个数,第一种组合return;//返回该函数最开始的位置,开始下一种组合
}DFS(index+1,w,v);//下标不为index,volu与value值不变if(w+volu[index]<=volumn){//满足条件if(v+value[index]>maxValue)//更新最大值maxValue=v+value[index];DFS(index+1,w+volu[index],v+value[index]);//走第二个岔路:下标为index,更新容量与价值}
}
int main(){cin>>num>>volumn;//输入物品数量与背包容量for(int i=0;i<num;i++)cin>>volu[i];//每件物品的容量for(int i=0;i<num;i++)cin>>value[i];//每件物品的价值DFS(0,0,0);//第0个容量、价值均为0cout<<maxValue<<endl;return 0;
}
小结
以深度作为遍历条件,碰到岔道时,选择一条岔道前进,直至碰到死胡同才返回岔道口并选择其它岔路,直至结点遍历完结束。