您的位置:首页 > 其它

超大背包问题

2017-03-04 22:17 267 查看
#include<iostream>
#include<math.h>
#include<algorithm>
#include<stdio.h>
#define INF 10000000
typedef long long ll;
using namespace std;
int n;
ll w[41],v[41],W;
pair<ll,ll> ps[1<<21];
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>w[i]>>v[i];
}
cin>>W;
//枚举前半部分 二进制枚举
int n2=n/2;
for(int i=0;i<1<<n2;i++)
{
ll sw=0,sv=0;
for(int j=0;j<n2;j++)
{
if(i>>j&1)
{
sw+=w[j];
sv+=v[j];
}
}
ps[i]=make_pair(sw,sv);
}

//去掉多余元素(价值小重量大)
sort(ps,ps+(1<<n2));
int m=1;
for(int i=1;i<1<<n2;i++)
{
if(ps[m-1].second<ps[i].second)
{
ps[m++]=ps[i];
}
}

//枚举后半部分并求解
ll res=0;
for(int i=0;i<1<<(n-n2);i++)
{
ll sw=0,sv=0;
for(int j=0;j<n-n2;j++)
{
if(j>>i&1)
{
sw+=w[n2+j];
sv+=v[n2+j];
}
}
if(sw<=W)
{
//找到前半部分中加起来不超重的价值最大者
ll tv=(lower_bound(ps,ps+m,make_pair(W-sw,(ll)INF))-1)->second;
res=max(res,sv+tv);
}
}
cout<<res<<endl;
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: