一个用搜索解01背包问题的强力剪枝

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<bits/stdc++.h>
using namespace std;

const int maxn = 100,MAX_V=1005,INF=0x3f3f3f3f;
int n=4,m,vis[15],V;
typedef long long LL;
typedef pair<int,int> P;
LL ans;
LL rv,cw,C,x[100],cv;
struct  node{
    int w,v;
    node(int a,int b){ w=a; v=b;}
    bool operator < (node& x){//将物品按重量从小到大分组,每组中价值大的放前面
        return w<x.w||(w==x.w&&v>x.v);
    }
};
vector<node> N;
void dfs(int i,int bound){  //搜索,bound为取物品的标准
   if (i>=n){
       ans=max(ans,cv);
       return ;
   }
   rv-=N[i].v;    //当前最多能取得的价值
   if (cw+N[i].w<=C&&N[i].v>bound){ //如果不超重且这组物品的价值比bound大,取之
       x[i]=1;cw+=N[i].w;cv+=N[i].v;
       dfs(i+1,bound);
       cw-=N[i].w;cv-=N[i].v;
   }
   if (cv+rv>ans){  //未来取到的价值有可能比当前解更优
       x[i]=0;
       dfs(i+1,max(N[i].v,bound));  //不取当前物品,更新bound,可以这样考虑,在当前重量下都不取该物品,
                                    //则同组的其他物品不会比它更好,而后面的物品价值若比它还低,也没有取的必要,那么不如
                                    // 把这个空间留给性价比更高的物品
   }
   rv+=N[i].v;
}
int main(){
    scanf("%d%d",&n,&C);
    for (int i=0;i<n;i++){
        int v,w;
        scanf("%d%d",&w,&v);
        rv+=v;
        N.push_back(node(w,v));
    }
    sort(N.begin(),N.end());
    dfs(0,0);
    printf("%lld\n",ans);
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值