2018QBXT刷題遊記(19)
阿新 • • 發佈:2018-11-07
【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;
}