【11.4 测试】Market

Input file: market.in
Output file: market.out
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 market.out
5 2
5 5 4
1 3 1
3 4 3
6 2 2
4 3 2
3 8
5 9
10
12

第一个计划可以在商店 2,3,5 各购买一件物品,总花费为 1 + 3 + 4 = 8,总价值为 3 + 4 + 3 = 10。
第二个计划可以在商店 1,2,3 各购买一件物品,总花费为 5 + 1 + 3 = 9,总价值为 5 + 3 + 4 = 12。

Notes
对于 100% 的数据, 1 ≤ ti; Ti ≤ n。

测试点编号 n m ci; Mi vi ti; Ti
1 = 10 = 5 ≤ 10 ≤ 10 ≤ 10
2 = 20 = 10 ≤ 100 ≤ 100 ≤ 20
3 = 100 = 1 ≤ 100 ≤ 100 = 1
4 = 200 = 1 ≤ 200 ≤ 200 = 1
5 = 150 = 100000 ≤ 150 ≤ 150 ≤ 150
6 = 300 = 100000 ≤ 300 ≤ 300 ≤ 300
7 = 20 = 100000 ≤ 109 ≤ 300 ≤ 20
8 = 200 = 100000 ≤ 109 ≤ 200 ≤ 200
9 = 300 = 100000 ≤ 109 ≤ 300 ≤ 300
10 = 300 = 100000 ≤ 109 ≤ 300 ≤ 300

 

题解:这道题01背包优化,注意用二分(因为他有单调性啊qwq)

         安利一下,这篇题解特别棒 https://blog.csdn.net/wu_tongtong/article/details/75305310

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int N=501;
int n,m;
struct node{
    int c,v,t;
}e[N];
int T,M,mx=0;
ll f[N*N];  
struct data{
    int t,m,id,ed;
}q[1000010];
int ans[1000010]; 

int cmp(node a,node b){
    if (a.t!=b.t) return a.t<b.t;
    else return a.c>b.c;
}
int cmp2(data a,data b){ 
    if (a.ed!=b.ed) return a.ed<b.ed;
    else return a.m>b.m;
}

int fathest(int x){ //记录一下每个询问可以最远去哪个商店购买
    int l=1,r=n;
    int ans=0;        
    while (l<=r){ 
        int mid=(l+r)>>1;
        if (e[mid].t<=x) ans=max(ans,mid),l=mid+1;
        else r=mid-1;
    }
    return ans;
}

void ido_ycll(){
    int k=1;
    while ( !q[k].ed && k<=m) k++;  //一个商店也去不了,这种询问跳过 
    memset(f,0x3f,sizeof(f));
    f[0]=0;
    for(int i=1;i<=n;i++){
        for(int j=mx;j>=e[i].v;j--)  
            f[j]=min(f[j],f[j-e[i].v]+(ll)e[i].c);
        int last=mx;
        while(q[k].ed==i && k<=m){ 
            for (int s=last;s>=1;s--)
                if (f[s]<=q[k].m)   
                   { ans[q[k].id]=s; last=s; break; }
            k++;
        } 
    }
}

int main()
{
    freopen("market.in","r",stdin);  
    freopen("market.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++){
        scanf("%d %d %d",&e[i].c,&e[i].v,&e[i].t);
        mx+=e[i].v;
    }
    sort(e+1,e+1+n,cmp);
    for (int i=1;i<=m;i++){
        scanf("%d %d",&q[i].t,&q[i].m);
        q[i].id=i;
    }
    for (int i=1;i<=m;i++)
        q[i].ed=fathest(q[i].t);//最远能去的那个商店的编号 
    sort(q+1,q+1+m,cmp2);
    ido_ycll();
    for (int i=1;i<=m;i++)
        printf("%d\n",ans[i]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wuhu-JJJ/p/11792952.html