题目:n个物品,时间限制m,给出每个物品的价值和时间,求在m限制内,最多的价值。
思路:大容量背包问题,采用贪心+搜索+剪枝的方法,先对所有的物品按贡献(w/v)进行排序, 当搜到第u个点时,第u+1个在剩下的贡献是最大的. 如果剩下空间的全部放 u+1物品都无法大于当前的答案,则剪去。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef long double LD;
const int N = 108;
struct data{
LL w, val;
bool operator<(const data &tp)const{
return val * tp.w > tp.val * w;
}
}pk[N];
int n;
LL lim,ans;
void dfs(int d, LL w, LL val){
if(val > ans) ans = val;
if(d >= n) return;
if(val + (LD)pk[d].val / (LD)pk[d].w * (lim - w)<= ans) return;
if(w + pk[d].w <= lim) dfs(d + 1, w + pk[d].w, val + pk[d].val);
dfs(d + 1, w, val);
}
int main(){
while(~scanf("%d %I64d", &n, &lim)){
for(int i = 0; i < n; i++) scanf("%I64d %I64d", &pk[i].w, &pk[i].val);
sort(pk, pk + n);
ans = 0;
dfs(0, 0, 0);
printf("%I64d\n", ans);
}
return 0;
}