【2018QBXT刷题游记】
Day5 TEST7
T1 herb
【问题描述】
小奇是只天资聪颖的喵,他的梦想是成为世界上最伟大的医师。
为此,他想拜喵星球最有威望的医师为师。
医师为了判断他的资质,给他出了一个难题。
医师把他带到⼀个到处都是草药的山洞里对他说:“小奇,这个山洞里有一些不同的草药,采每⼀株都需要⼀些时间,每⼀株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到⼀些草药。
如果你是一只聪明的喵,你应该可以让采到的草药的总价值最大。”
【输入格式】
输入文件名为 herb.in
第 1 行包括 1 个整数 T,表示数据组数。
对于每组数据,第 1 行包括 2 个整数, n, m,表示草药的数目和能用于采
药的时间。
接下来 n 行,每行两个整数 ti;vi。
保证 m;ti;vi 在限制范围内均匀随机生成。
【输出格式】
输出文件名为 herb.out
输出 T 组,每组 1 个数字,表示每组数据答案。
【样例输入】
1
3 70
71 100
69 1
1 2
【样例输出】
3
【数据规模与约定】
对于 30% 数据,
对于 60% 数据,
对于 100% 数据,
【分析】60分就是01背包模板
然鹅100分数据范围有点大。
考虑到m,ti,vi 在限制范围内均匀随机生成,那么不会选太多的草药,耗时较少的草药有很大概率存在于最优解中。
针对这些性质优化搜索。
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m;
ll ans;
ll sw[205],sv[205];
struct data{
int w,val;
}a[205];
bool operator<(data a,data b)
{
return a.w>b.w;
}
void dfs(int x,ll sumw,ll sumv)
{
ans=max(ans,sumv);
if(sumw+a[n].w>m)return;
if(sumv+sv[x]<ans)return;
if(sumw+sw[x]<=m)
{
ans=max(ans,sumv+sv[x]);
return;
}
if(sumw+a[x].w<m)
dfs(x+1,sumw+a[x].w,sumv+a[x].val);
dfs(x+1,sumw,sumv);
}
int main()
{
freopen("herb.in","r",stdin);
freopen("herb.out","w",stdout);
int T=read();
while(T--)
{
n=read();m=read();
ans=0;
for(int i=1;i<=n;i++)
a[i].w=read(),a[i].val=read();
sort(a+1,a+n+1);
sw[n+1]=sv[n+1]=0;
for(int i=n;i>=1;i--)
{
sw[i]=sw[i+1]+a[i].w;
sv[i]=sv[i+1]+a[i].val;
}
dfs(1,0,0);
cout<<ans<<endl;
}
return 0;
}