【JZOJ4863】Market

来源:互联网 发布:更改网卡mac地址win10 编辑:程序博客网 时间:2024/06/05 22:50

Description

现在有一些物品,第i个物品的花费,价值,出现的时间分别为civiti,每个物品只能获得一次,现在对于每个询问TiMi,表示在Ti时刻购买,预算为M_i,求获得的最大价值。

Data Constraint

n300,m105
ci,Mi109,vi300
ti,Ti300

Solution

对询问和物品按照时间排序,按照询问依次加入物品。

Fi表示花费i获得的最大价值,但我们发现这样时间空间都超出范围。

我们发现价值很小,于是我们可以设Fi表示获得价值i所用的最小花费,转移与上面的方法类似。

找答案时就取个后缀最小值,二分答案即可。

Code

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)#define N 310#define M 100010#define ll long longusing namespace std;struct node{    int c,v,t;}b[N];struct node1{    int m,t,c;}c[M];int f[M],g[M+1];int z[M];bool cmp(node x,node y){    return x.t<y.t;}bool cmp1(node1 x,node1 y){    return x.t<y.t;}int main(){    freopen("market.in","r",stdin);    freopen("market.out","w",stdout);    int n,m;    cin>>n>>m;    fo(i,1,n) scanf("%d %d %d",&b[i].c,&b[i].v,&b[i].t);    fo(i,1,m) scanf("%d %d",&c[i].t,&c[i].m),c[i].c=i;    sort(b+1,b+n+1,cmp);    sort(c+1,c+m+1,cmp1);    int q=0;    memset(f,60,sizeof(f));    f[0]=0;    memset(g,60,sizeof(g));    fo(i,1,m)    {        while(b[q+1].t<=c[i].t && q<n)        {            q++;            g[M]=2147483647;            fd(j,M-1,0)            {                if(j>=b[q].v)                {                    if(f[j]>f[j-b[q].v]+b[q].c)                    {                        f[j]=f[j-b[q].v]+b[q].c;                    }                }                g[j]=min(f[j],g[j+1]);            }            g[0]=0;        }        int ans=0;        int l=0,r=M-1;        while(l+1<r)        {            int mid=(l+r)/2;            if(g[mid]<=c[i].m) l=mid;            else r=mid;        }        ans=l;        if(g[r]<=c[i].m) ans=r;        z[c[i].c]=ans;    }    fo(i,1,m) printf("%d\n",z[i]);}
1 0
原创粉丝点击