Problem B. Market(market.c/cpp/pas)
Time limit: 1 seconds
Memory limit: 128 megabytes
在比特镇一共有 n 家商店,编号依次为 1 到 n。每家商店只会卖一种物品,其中第 i 家商店的物品单价为 ci,价值为 vi,且该商店开张的时间为 ti。Byteasar计划进行m次购物,其中第i次购物的时间为Ti,预算为Mi。每次购物的时候,Byteasar会在每家商店购买最多一件物品,固然他也能够选择什么都不买。若是购物的时间早于商店开张的时间,那么显然他没法在这家商店进行购物。如今 Byteasar 想知道,对于每一个计划,他最多能购入总价值多少的物品。请写一个程序,帮助Byteasar 合理安排购物计划。
注意:每次所花金额不得超过预算,预算也不必定要花完,同时预算不能留给其它计划使用。
Input
第一行包含两个正整数 n;m,表示商店的总数和计划购物的次数。
接下来 n 行,每行三个正整数 ci; vi; ti,分别表示每家商店的单价、价值以及开张时间。
接下来 m 行,每行两个正整数 Ti;Mi,分别表示每一个购物计划的时间和预算。
Output
输出 m 行,每行一个整数,对于每一个计划输出最大可能的价值和。
Examples
market.in
5 2
5 5 4
1 3 1
3 4 3
6 2 2
4 3 2
3 8
5 9c++
market.out
10
12
第一个计划能够在商店 2,3,5 各购买一件物品,总花费为 1 + 3 + 4 = 8,总价值为 3 + 4 + 3 = 10。
第二个计划能够在商店 1,2,3 各购买一件物品,总花费为 5 + 1 + 3 = 9,总价值为 5 + 3 + 4 = 12。git
解析:spa
动规;code
由于正向的想法没法实现。因此反向思考。令f[i]为装了i的总价值时用的最少的钱;blog
将商店与问题的T按从小到大排序,这样的话就能简化运算的速度;排序
f[i]最后要与i以后的进行比较,取最小值;ci
进行二分;get
#include<bits/stdc++.h> using namespace std; #define ll long long #define rint register int inline int read(){ int x=0,f=0;char ch=getchar(); while(!isdigit(ch)) f=(ch==45),ch=getchar(); while( isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?(~x+1):x; } #define man 330 struct mono{ int val,w,t;}a[man<<1]; struct obj{ int t,m,id;}b[100010]; int cmp(mono a,mono b){ return a.t<b.t; } int ccmp(obj a,obj b){ return a.t<b.t; } int n,m,tot,f[100010],ans[100010]; const int inf=1e9+7; inline void dp(int val,int w){ for(rint i=tot;i>=val;i--) f[i]=min(f[i],f[i-val]+w); for(rint i=tot-1;i>0;i--) f[i]=min(f[i],f[i+1]); } inline int search(int w){ int l=0,r=tot,mid,ans; while(l<=r){ mid=(l+r)>>1; if(f[mid]<=w) ans=mid,l=mid+1; else r=mid-1; } return ans; } int main(){ freopen("market.in","r",stdin); freopen("market.out","w",stdout); n=read();m=read();tot=n*300; for(rint i=1;i<=n;i++) a[i].w=read(),a[i].val=read(),a[i].t=read(); for(rint i=1;i<=m;i++) b[i].t=read(),b[i].m=read(),b[i].id=i; sort(a+1,a+1+n,cmp); sort(b+1,b+1+m,ccmp); for(rint i=1;i<=tot;i++) f[i]=inf; for(rint i=1,j=1;i<=m;i++){ while(j<=n&&a[j].t<=b[i].t) dp(a[j].val,a[j].w),j++; ans[b[i].id]=search(b[i].m); } for(rint i=1;i<=m;i++) printf("%d\n",ans[i]); return 0; }