您的位置:首页 > 其它

【GDOI2017模拟11.5】Market

2016-11-05 15:14 295 查看

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]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: