【GDOI2017模拟11.5】Market

来源:互联网 发布:sqlserver sp3下载 编辑:程序博客网 时间:2024/05/03 05:20

Description

这里写图片描述

Solution

这题一眼就是离线之后,用DP来做。
但是一开始我用单价和来做DP的键值,但是没有发现,单价的范围很大。所以应该以价值来做键值,然后存最小需要的单价和。求答案的时候二分就好了。

Code

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)#define fod(i,a,b) for(i=a;i>=b;i--)using namespace std;const int maxn=307,mxx=100007;int i,j,k,l,n,m,o,zong;typedef long long ll;struct node{    ll c,v,t,u;}a[mxx],b[mxx];ll f[maxn*maxn],ans[mxx],g[mxx];ll r,mid;bool cmp(node x,node y){return x.t<y.t;}int main(){    freopen("market.in","r",stdin);    freopen("market.out","w",stdout); //   freopen("fan.in","r",stdin);  //  freopen("fan.out","w",stdout);    scanf("%lld%lld",&n,&m);    fo(i,1,n)scanf("%lld%lld%lld",&a[i].c,&a[i].v,&a[i].t),zong+=a[i].v;    sort(a+1,a+1+n,cmp);    fo(i,1,m)scanf("%lld%lld",&b[i].t,&b[i].c),b[i].u=i;    sort(b+1,b+1+m,cmp);    memset(f,127,sizeof(f));memset(g,127,sizeof(g));    f[0]=0;g[0]=0;    fo(i,1,m){        l=o;        while(o+1<=n&&a[o+1].t<=b[i].t)o++;        fo(j,l+1,o){            fod(k,zong,a[j].v){                if(f[k-a[j].v]+a[j].c<f[k]){                    f[k]=f[k-a[j].v]+a[j].c;                 }            }              fod(k,zong,0)g[k]=min(g[k+1],f[k]);          }        l=0,r=zong;        while(l<r){            mid=(l+r+1)/2;            if(g[mid]>b[i].c)r=mid-1;else l=mid;        }        ans[b[i].u]=l;    }    fo(i,1,m)printf("%lld\n",ans[i]);}
2 0