dfs背包问题

#include<cstdio>
#include<algorithm>
#include<string>
#include<queue>
#include<iostream>
using namespace std;
const int maxn=30;
int n,V,w[maxn],c[maxn],res=0;
void dfs(int index,int sumW,int sumC){
    if(index==n){//死胡同,到头了
        if(sumW<=V&&sumC>res)
            res=sumC;
        return ;
    }
    dfs(index+1,sumW,sumC);//不选第index件物品
    dfs(index+1,sumW+w[index],sumC+c[index]);//选第index件物品
}
int main(){
    scanf("%d %d",&n,&V);
    for(int i=0;i<n;i++)
        scanf("%d",&w[i]);
    for(int i=0;i<n;i++)
        scanf("%d",&c[i]);
    dfs(0,0,0);
    printf("%d",res);
    return 0;
}
/*
5 8
3 5 1 2 2
4 5 2 1 3

10
*/

算法复杂度:O(2^n)

dfs岔道口:第index件物品选/不选

dfs死胡同:所选物品重量大于V

当index=n时表示n件物品已经处理完毕,此时的sumW若小于V且sumC大于当前res,则更新res。

可以做如下优化:在以上代码中,总是等n件物品都确定好装/不装后才试图更新res,若中途sumW>V了,那么可直接试图更新res。即只有sumW<=V时才进入岔道口。如下:

void dfs(int index,int sumW,int sumC){
    if(index==n){//死胡同,到头了
        return ;
    }
    dfs(index+1,sumW,sumC);//不选第index件物品,所以可直接进入岔路口
    if(sumW+w[index]<=V){//若选第index件物品,判断一下是否还有空间再决定是否进入岔路口
        if(sumC+c[index]>res)
            res=sumC+c[index];
        dfs(index+1,sumW+w[index],sumC+c[index]);//选第index件物品
    }
}

猜你喜欢

转载自blog.csdn.net/ur_ytii/article/details/112728511