DFS写背包问题

dfs解决背包问题

#include <iostream>
///用深搜写
using namespace std;
int weight,maxvalue=0,n;///背包中能放物品的总质量weight,最大价值maxvalue,总的物品数量
int v[30],w[30];///物品的数量和价值
void dfs(int index,int sumw,int sumv)///第index件物品,选择的总质量sumw,总价值sumv
{
    if(index==n)///死胡同,对所有的物品都选择完毕
    {
     if(sumw<=weight&&sumv>maxvalue)   ///若符合条件,则更新最大值
        maxvalue=sumv;
        return;///要返回停止,否则就是死循环了
    }
    ///要写index+1,不能写index++,否则出不来
    dfs(index+1,sumw+w[index],sumv+v[index]);  ///岔路口1:选择这件物品
    dfs(index+1,sumw,sumv);                    ///岔路口2:不选择,总的来说就是一个集合有多少个子集
}
int main()
{
    cin>>n>>weight;
    for(int i=0;i<n;i++)///从0开始
    {
        cin>>w[i];
    }
    for(int i=0;i<n;i++) cin>>v[i];///从0开始
    dfs(0,0,0);
    cout << maxvalue << endl;
    return 0;
}

通过减枝优化后的程序,若不遇到极端情况,效率提升许多

void DFS(int index,int sumw,int sumv)///减枝,优化一下
{
    if(index==n) return;
    DFS(index+1,sumw,sumv);///不选择
    if(sumw+w[index]<=weight)///选择的话,要先符合总质量要小于背包容量
    {
        if(maxvalue<sumv+v[index]) maxvalue=sumv+v[index];
        DFS(index+1,sumw+w[index],sumv+v[index]);
    }
}

具体的递归过程类似于下图,每次递归进入下一层都有两种分支(岔路口)

F(3){DFS(index+1,sumw+w[indes],sumv+v[index])},F(2){DFS(index+1,sumw,sumv)
代表F(4){DFS(index,sumw,sumv)}的两个岔路口

在这里插入图片描述
在这里插入图片描述
上代码

#include <bits/stdc++.h>
using namespace std;
int n,k,maxsumsqu=-1,x;///n个数中选择k个使得他们的和为x,求出平方和最大的一组数
int a[30];///集合内元素
vector<int>temp,ans;///temp存放临时最大的方案,ans存放最终方案
void dfs(int index,int nowk,int sum,int sumsqu)
{
    if(nowk==k&&sum==x)///符合选择的nowk==k个数和为x
    {
        if(sumsqu>maxsumsqu)
        {
            maxsumsqu=sumsqu;
            ans=temp;///更新最优方案
        }
        return ;
    }
    ///处理完n个数,或者超过k个数,或者和超过x,返回
    if(index==n||nowk>k||sum>x) return;
    ///选择index号方案
    temp.push_back(a[index]);
    dfs(index+1,nowk+1,sum+a[index],sumsqu+a[index]*a[index]);
    ///不选择index号方案
    temp.pop_back();
    dfs(index+1,nowk,sum,sumsqu);
}
int main()
{
    cin>>n>>k>>x;
    for(int i=0;i<n;i++)  cin>>a[i];
    dfs(0,0,0,0);
    for(int i=0;i<ans.size();i++) cout<<ans[i]<<" ";
    cout<<endl;
    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Spidy_harker/article/details/88523069