题目大意:
给你n个物品,每个物品有他的价值和花费的时间,问你在花费时间在val内的最大价值。
分析:
乍一看是一个背包问题,但是仔细观擦后发现,由于t有1e9那么大,所以不能使用背包来实现这个过程,由于相对来说,n不是很大,所有的n加起来不超过100,所以搜索。
具体剪枝操作是记录u到u+1的总价值和总时间。
最关键的在于,要按照时间从大到小的方式进行排序
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#include <vector>
#include <set>
using namespace std;
const int maxn = 100 + 10;
typedef long long ll;
struct node
{
ll t,v;
bool operator<(const node &rhs)const
{
return t>rhs.t;
}
}s[maxn];
ll n,val;
ll left_t[maxn];
ll left_v[maxn];
ll ans;
void dfs(int u,ll t,ll v)
{
ans=max(ans,v);
if(u==n+1) return ;
if(v+left_v[u]<ans)
return ;
if(t+left_t[u]<=val)
{
ans=max(ans,v+left_v[u]);
return ;
}
if(t+s[u].t<=val)
{
dfs(u+1,t+s[u].t,s[u].v+v);
}
dfs(u+1,t,v);
}
int main()
{
while(~scanf("%lld%lld",&n,&val))
{
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&s[i].t,&s[i].v);
}
memset(left_t,0,sizeof(left_t));
memset(left_v,0,sizeof(left_v));
sort(s+1,s+1+n);
for(int i=n;i>=1;i--)
{
left_t[i]+=(left_t[i+1]+s[i].t);
left_v[i]+=(left_v[i+1]+s[i].v);
}
ans=0;
dfs(1,0,0);
printf("%lld\n",ans);
}
return 0;
}