Problem B. Market(market.c/cpp/pas)

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;
}
相關文章
相關標籤/搜索