递归DFS背包问题求最优解

背包问题大家都知道,已知背包的最大存储量是V,给定n个物品,求取怎样盛放才能是背包价值最大。

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=30;
int n,V,maxValue=0;//n表示物品数量,V表示背包容量
//maxvalue表示最大价值
int z[maxn],j[maxn];
void DFS(int index,int sumZ,int sumJ){//sumZ sumJ表示当前质量和价值
	if(index==n){
	if(sumZ<=V&&sumJ>=maxValue)
		maxValue=sumJ;
		return;
}
	//不选区下标为index的物品
	DFS(index+1,sumZ,sumJ);
	//选区下标为index的物品
	DFS(index+1,sumZ+z[index],sumJ+j[index]);
}  
int main(){
cin>>n>>V;
for(int i=0;i<n;i++)
cin>>z[i];
for(int i=0;i<n;i++)
cin>>j[i];
DFS(0,0,0);
cout<<maxValue;
return 0;
}

输入:
5 8
3 5 1 2 2
4 5 2 1 3
输出:
10
分析:该代码的时间复杂度是n2,对于10000级别以上的数来说是不可接受的,此时我们可以室友高逼格的剪枝来优化,操作是把DFS函数中的质量和价值判断移到DFS(index+1,sumZ+z[index],sumJ+j[index]);之前,这样就能一定程度上减少代码时间复杂度


还有类似的题目是,给定n个整数,选取k个数,使k个数的和为x,如果存在多组解,则选区平方和最大的一组

代码未调试成功,暂存

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n,k,x,maxpf=0;
vector<int>tem;
vector<int>ans;
void DFS(vector<int> v,int index,int nowx,int nowk,int nowpf){
if(x==nowx&&nowk==k){
	if(nowpf>maxpf){
		maxpf=nowpf;
		ans=tem;
	}
	return;
}
if(index==n||nowk>k||nowx>x) return;
tem.push_back(v[index]);
DFS(v,index+1,nowx+v[index],nowk+1,nowpf+v[index]*v[index]);
tem.pop_back();
DFS(v,index+1,nowx,nowk,nowpf);
}  
int main(){
cin>>n>>k>>x;
vector<int>v(n);
for(int i=0;i<n;i++)
cin>>v[i];
DFS(v,0,0,0,0);
for(int i=0;i<ans.size();i++)
cout<<ans[i]<<" ";
return 0; 
}

输入:
4 2 5
1 2 3 4
输出:
1 4

猜你喜欢

转载自blog.csdn.net/Cai__ji/article/details/84987758