链接:点击打开链接
题意:大数据采药
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
long long n,w,ans;
struct node{
long long a,b;
friend bool operator<(node x,node y){
return x.a>y.a;
}
}s[105];
long long w_tmp[105],v_tmp[105];
void dfs(long long num,long long sum,long long val){
ans=max(ans,val);
if(num==n+1)
return;
if(val+v_tmp[num]<=ans) //价值小的时候不用继续,和
return; //能够全装下时直接全装进去
if(sum+w_tmp[num]<=w){
ans=max(ans,val+v_tmp[num]);
return;
}
if(sum+s[num].a<=w&&num+1<=n)
dfs(num+1,sum+s[num].a,val+s[num].b);
dfs(num+1,sum,val);
}
int main(){ //因为容量很大因此很明显用搜索
long long i,x,y,cnt,sum,sum_val; //但是可能是因为数据的原因,用
while(scanf("%I64d%I64d",&n,&w)!=EOF){ //一个后缀和优化就不超时......
cnt=1,sum=sum_val=0;
for(i=1;i<=n;i++){
scanf("%I64d%I64d",&x,&y);
if(x<=w){
s[cnt].a=x,s[cnt].b=y;
sum+=s[cnt].a;
sum_val+=s[cnt].b;
cnt++;
}
} //把体积大的直接删掉
if(cnt==1){
puts("0");
continue;
}
n=cnt-1;
if(sum<=w){ //全部装进去的时候
printf("%I64d\n",sum_val);
continue;
}
sort(s+1,s+n+1);
w_tmp[n+1]=v_tmp[n+1]=0;
for(i=n;i>=1;i--){ //维护后缀组数
w_tmp[i]=s[i].a+w_tmp[i+1];
v_tmp[i]=s[i].b+v_tmp[i+1];
}
ans=0;
dfs(1,0,0);
printf("%I64d\n",ans);
}
return 0;
}