DFS的入门应用
有n件物品,每件物品的重量为w[i],价值为c[i].现在需要选出若干件物品放入一个容量为v的背包中,使得在选入背包的物品重量和不超过容量v的前提下,让背包中物品的价值之和最大,求最大的价值。(1<=n<=20)
分析:将每个点的选与不选作为两种状态,利用DFS,在将选与不选作为状态后,遍历全部的n个点,找出其中的最大值,其中边界为不超过容量v和遍历完n个点,复杂度为O(2n)
ps:此题其实是一个 01背包问题,但也可以转化为dfs求解
#include<iostream>
#include<algorithm>
using namespace std;
//dfs
const int maxn=30;
int w[maxn],c[maxn];
int maxvalve=0;
int v,n;
void dfs(int now_w,int now_c,int index)
{
if(index==n) //choose or not choose to be two states , n points that must be traversed //遍历完n个点
{ //
if(now_w<=v&&now_c>maxvalve)//在满足条件的前提下比较所有 遍历过n个点状态 的所有最值
{
maxvalve=now_c;
}
return ;
}
dfs(now_w,now_c,index+1); //not choose this point//不选的状态
dfs(now_w+w[index],now_c+c[index],index+1);//choose this point//选的状态
}
int main()
{
cin>>n>>v;
for(int i=0;i<n;i++)
cin>>w[i];
for(int j=0;j<n;j++)
cin>>c[j];
dfs(0,0,0);
cout<<maxvalve<<endl;
return 0;
}
分析二:上述解法复杂度较高,可以优化在选择当前点时,就进行判断,降低复杂度
void DFS(int index,int now_w,int now_c)
{
if(index==n) return ; //遍历了n个点,返回
DFS(index+1,now_w,now_c);//不选的状态
if(now_w+w[index]<=v)//满足v条件则可以进行选的状态,否则只能进行不选的状态
{
if(now_c+c[index]>maxvalve)//满足maxvalve条件则刷新最大值,若不满足则直接进入下一选的状态
{
maxvalve=now_c+c[index];
}
DFS(index+1,now_w+w[index],now_c+c[index]);
}
}