1. 程式人生 > >2018QBXT刷題遊記(19)

2018QBXT刷題遊記(19)

【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% 資料, 1

n 20 ; 1 m v i
t i 1 0 4 1 ≤ n ≤ 20; 1 ≤ m,vi,ti ≤ 10^4

對於 60% 資料, 1 n 100 ; 1 m v i t i 1 0 5 1 ≤ n ≤ 100; 1 ≤ m,vi,ti ≤ 10^5
對於 100% 資料, 1 T 10 ; 1 n 150 ; 1 m v i t i 1 0 9 1 ≤ T ≤ 10; 1 ≤ n ≤ 150; 1 ≤ m,vi,ti ≤ 10^9

【分析】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;
}