【简】题解 AWSL090429 【市场】

因为这有个时间的限制 并且  求的时间都是前缀和

那么 我们可以根据时间将排序

因为题中没有修改可以直接用背包预处理出答案

但是因为题目ci mi<=1e9   vi<=300

所以发现不能直接背包

发现vi很小 每个商品只能被选一次  能达到的最大的价值就是n*n

因为vi越大 费用单调不减 就可以二分求

#include<bits/stdc++.h> 
using namespace std;
#define ll long long
#define C getchar()-48
inline ll read()
{
    ll s=0,r=1;
    char c=C;
    for(;c<0||c>9;c=C) if(c==-3) r=-1;
    for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
    return s*r;
} 
const int N=310,M=1e5+10,inf=1e9+10;
int n,m;
struct xin{
    int c,v,t;
}a[N]; 
int c[N],v[N],t[N];
int ans[N][M];// 位置  预算 
inline bool pd(xin a,xin b)
{
    return a.t<b.t;
}
int main()
{
    freopen("market.in","r",stdin);
    freopen("market.out","w",stdout); 
    n=read(),m=read();
    for(int i=1;i<=n;i++) a[i].c=read(),a[i].v=read(),a[i].t=read();
    sort(a+1,a+1+n,pd);
    for(int i=1;i<=n;i++) c[i]=a[i].c,v[i]=a[i].v,t[i]=a[i].t;
    for(int i=0;i<=n;i++)
    for(int j=1;j<=N*N;j++)
      ans[i][j]=inf;
    for(int i=1;i<=n;i++)
    {
        int r=0;
        for(int j=1;j<v[i];j++) ans[i][j]=min(ans[i-1][j],c[i]);
        for(int j=v[i];j<=310*310;j++) ans[i][j]=min(ans[i-1][j],ans[i-1][j-v[i]]+c[i]);
    } 
    for(int i=1;i<=m;i++)
    {
        int tt=read(),mm=read();
        int r=upper_bound(t+1,t+1+n,tt)-t-1;
        int rr=upper_bound(ans[r]+1,ans[r]+1+300*300,mm)-ans[r]-1;
        printf("%d\n",rr);
    }
    return 0;
}
posted @ 2019-04-29 14:10  1436177712  阅读(110)  评论(0编辑  收藏  举报