题意:
给你一个背包,有确定的背包容量。然后有许多商品,每个商品有它的体积和价值,问你最多能装多少。
很明显的一个01背包问题,但是体积和价值1e9 非常大,不能dp
搜索的话100个物品, 直接暴搜2^100 也会爆掉。
那么只能剪枝喽, 先把所有物品按照性价比排序,
然后依次取得时候,按照当前剩余容量后面按照性价比,能取多少取多少,肯定是最大收益,如果这样都不能使结果变得更优,那么就再往下dfs、
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=100+5;
int n,m,k;
ll ans,T;
int stone[maxn];
struct node{
ll bill,val;
}herb[maxn];
bool cmp(node a,node b){
return a.val*b.bill>a.bill*b.val;
}
bool check(int i,ll weight,ll sum){
for(int j=i;j<=n;++j){
if(weight+herb[j].bill<=T) weight+=herb[j].bill,sum+=herb[j].val;
else {
sum+=herb[j].val*1.0/herb[j].bill*(T-weight);
break;
}
}
return sum>ans;
}
void dfs(int i,ll weight,ll sum){
ans=max(ans,sum);
if(i<=n&&check(i,weight,sum)){
if(weight+herb[i].bill<=T)dfs(i+1,weight+herb[i].bill,sum+herb[i].val);
dfs(i+1,weight,sum);
}
}
int main(){
// scanf("%d",&T);
// for(int ca=1;ca<=T;++ca){
// }
while(~scanf("%d %lld",&n,&T)){
ans=0;
for(int i=1;i<=n;++i)
scanf("%lld %lld",&herb[i].bill,&herb[i].val);
sort(herb+1,herb+n+1,cmp);
dfs(1,0,0);
printf("%lld\n",ans);
}
return 0;
}