【NOIp模拟赛】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

分析

这很显然是一个背包问题,前60分是很好写的,但是后面的背包容量就有点大了,我们开不了这么大的数组,但仔细观察数据你会发现vi是很小的,所以用二分+动态规划就行了。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=300+5;
const int maxm=100000+5;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
int n,m,now,tail,lim;
int ans[maxm],q[maxm],f[maxn*maxn];
struct node{int c,v,t;}a[maxn];
struct data{int t,m,id;}b[maxm];
bool cmp1(node x,node y){return x.t<y.t;}
bool cmp2(data x,data y){return x.t<y.t;}
inline void add(int v,int c)
{
    for(int i=lim;i>=v;i--) f[i]=min(f[i],f[i-v]+c);
    for(int i=lim-1;i>=0;i--) f[i]=min(f[i],f[i+1]);
}
inline int query(int x)
{
    int l=0,r=lim,ans;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(f[mid]<=x) {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(); lim=n*301;
    for(int i=1;i<=n;i++)
        a[i].c=read(),a[i].v=read(),a[i].t=read();
    for(int i=1;i<=m;i++)
        b[i].t=read(),b[i].m=read(),b[i].id=i;
    sort(a+1,a+n+1,cmp1);
    sort(b+1,b+m+1,cmp2);
    memset(f,0x3f,sizeof(f)); f[0]=0;
    for(int i=1;i<=m;i++)
    {
        now=tail+1;
        if(now<=n)
        for(int j=now;j<=n;j++)
        if(b[i].t>=a[j].t) {add(a[j].v,a[j].c); tail++;} 
        else break;
        ans[b[i].id]=query(b[i].m);
    }
    for(int i=1;i<=m;i++)
        printf("%d
",ans[i]);
    return 0;
}
    


欢迎转载,转载请注明出处!
原文地址:https://www.cnblogs.com/huihao/p/7505889.html