4863. 【GDOI2017模拟11.5】Market

来源:互联网 发布:少儿英语 知乎 编辑:程序博客网 时间:2024/05/19 23:13

Description

这里写图片描述

Data Constraint

这里写图片描述

Solution

对于60分的解法,我们直接打个背包即可。然后我们发现:M[I]实在太大了,所以我们设出f[i]表示在价值为i的情况下的最小代价,转移方式与原来相同,然后每个询问二分一下答案即可。由于v[i]*n最多只有90000,所以复杂度为O(300n2)。

Code

#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<algorithm>#define ll long longusing namespace std;const int maxn=100005,mx=90000;struct code{    int a,b,c;}a[maxn],b[maxn];ll n,m,i,t,j,k,l,r,mid,f[mx+5],ans[maxn],g[mx+5];bool cmp(code x,code y){    return x.c<y.c;}int main(){    freopen("market.in","r",stdin);freopen("market.out","w",stdout);//freopen("data.in","r",stdin);freopen("data.out","w",stdout);    scanf("%lld%lld",&n,&m);    for (i=1;i<=n;i++)        scanf("%lld%lld%lld",&a[i].a,&a[i].b,&a[i].c);    sort(a+1,a+n+1,cmp);    for (i=1;i<=m;i++)        scanf("%lld%lld",&b[i].c,&b[i].a),b[i].b=i;    sort(b+1,b+m+1,cmp);j=1;    memset(f,127,sizeof(f));f[0]=0;memset(g,127,sizeof(g));    for (i=1;i<=m;i++){        while (a[j].c<=b[i].c && j<=n){            for (k=mx-a[j].b;k>=0;k--)                if (f[k]>=0)f[k+a[j].b]=min(f[k+a[j].b],f[k]+a[j].a);            for (k=mx;k>=0;k--)                g[k]=min(g[k+1],f[k]);            j++;        }        l=0;        r=mx;        while (l<r){            mid=(l+r+1)/2;            if (g[mid]>b[i].a) r=mid-1;            else l=mid;        }        ans[b[i].b]=l;    }    for (i=1;i<=m;i++)        printf("%lld\n",ans[i]);}
3 0
原创粉丝点击