算法笔记8 DFS

1.有N个物品,每个物品都有重量和价格,在不超过背包容量V的情况下选出价格之和最大,求最大价值maxValue。

思路,每个物品都有2种方法,选择或不选择,相当于迷宫的岔路口,递归中的递归式。而当物品总重量超过背包容量V,在相当于迷宫中的死胡同,递归中的递归边界。通过枚举所有选择方案,来得出最优解。
其中DFS是常规解,DFS_better是用了剪枝技巧的优化解

#include 

using namespace std;
const int maxn = 30; 

int n,V,maxValue = 0;
int w[maxn],c[maxn];

//index为当前物品编号,sumW,sumC为当前的总重量和总价值 
void DFS(int index, int sumW, int sumC){
	
	if(index == n){		//当完成对n个物品的选择,把最大价值给输出 
		if( sumW <= V && sumC > maxValue){
			maxValue = sumC;			
		}
		return ;
	}
 	
 	//岔道口,选择还是不选择 
	DFS( index+1, sumW, sumC);		//不选择第index号物品,index(0~n-1); 
	DFS( index+1, sumW+w[index], sumC+c[index]);		//选择第index号物品,则加上其重量和价值 
} 

//优化后的 
void DFS_better(int index ,int sumW, int sumC){
	
	if(index == n) return;
	
	DFS(index+1, sumW,sumC);
	
	if(sumW + w[index] <= V){		//若将当前第index号物品加入后不超过总容量才进行选择 
		if(sumC +c[index] > maxValue){
			maxValue = sumC + c[index];
		}
		DFS(index+1, sumW + w[index],sumC + c[index]);
	}

} 
int main(){
	
	scanf("%d%d", &n,&V);
	
	for(int i=0; i

这适用于一类DFS问题的解决方法,即给定一个序列,枚举这个序列的所有子序列(可以不连续)。例如对序列{1,2,3)来说,它的所有子序列为{I}、 {2}、 {3)、 {1,2}、{1,3}、 {2,3)、{1,2,3)。枚举所有子序列的目的很明显―可以从中选择一个 “最优”子序列,使它的某个特征是所有子序列中最优的;如果有需要,还可以把这个最优子 序列保存下来。显然,这个问题也等价于枚举从N个整数中选择K个数的所有方案。

你可能感兴趣的:(算法笔记)