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; }