JZOJ 5459 购物

Time Limits: 1000 ms Memory Limits: 524288 KB Detailed Limits

Description

小X 正困在一个密室里,他希望尽快逃出密室。
密室中有N 个房间,初始时,小X 在1 号房间,而出口在N 号房间。
密室的每一个房间中可能有着一些钥匙和一些传送门,一个传送门会单向地创造一条从房间X 到房间Y 的通道。另外,想要通过某个传送门,就必须具备一些种类的钥匙(每种钥匙都要有才能通过)。幸运的是,钥匙在打开传送门的封印后,并不会消失。
然而,通过密室的传送门需要耗费大量的时间,因此,小X 希望通过尽可能少的传送门到达出口,你能告诉小X 这个数值吗?
另外,小X 有可能不能逃出这个密室,如果是这样,请输出”No Solution”。

Input

第一行三个整数N,M,K,分别表示房间的数量、传送门的数量以及钥匙的种类数。
接下来N 行,每行K 个0 或1,若第i 个数为1,则表示该房间内有第i 种钥匙,若第i 个数为0,则表示该房间内没有第i 种钥匙。
接下来M 行,每行先读入两个整数X,Y,表示该传送门是建立在X 号房间,通向Y 号房间的,再读入K 个0 或1,若第i 个数为1,则表示通过该传送门需要i 种钥匙,若第i 个数为0,则表示通过该传送门不需要第i 种钥匙。

Output

输出一行一个“No Solution”,或一个整数,表示最少通过的传送门数。

Sample Input

3 3 2
1 0
0 1
0 0
1 3 1 1
1 2 1 0
2 3 1 1

Sample Output

2

扫描二维码关注公众号,回复: 2647760 查看本文章

这里写图片描述

解题思路

贪心,首先按照优惠价排序,之后用一个优先队列去维护一个size为k的差价,表示这k个买优惠价,每次看新加入的是否更优。之后再用一个优先队列存用原价买的,时间复杂度O(nlogn)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>

using namespace std;
const int MAXN = 50005;
typedef long long LL;

inline LL rd(){
    LL x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    return x*f;
}

struct Data{
    int diff;
    LL a,q;
    bool operator < (const Data A)const{
        return A.diff<=diff;
    }
}data[MAXN];

int n,k;
LL m,ans,sum;
priority_queue<Data> Q;
priority_queue<LL> q;

inline bool cmp(Data A,Data B){
    return A.q<B.q;
}

int main(){
    freopen("shopping.in","r",stdin);
    freopen("shopping.out","w",stdout);
    n=rd();k=rd();m=rd();
    for(register int i=1;i<=n;i++) {
        data[i].a=rd();
        data[i].q=rd();
        data[i].diff=data[i].a-data[i].q;
    }
    sort(data+1,data+1+n,cmp);
    for(register int i=1;i<=n;i++){
        if(Q.size()<k && data[i].q+sum<=m) {
            Q.push(data[i]);
            sum+=data[i].q;
            ans++;
        }
        else if(Q.size()==k){
            Data x=Q.top();
            if(x.diff+data[i].q<data[i].a){
                Q.pop();Q.push(data[i]);
                sum=sum-x.q+data[i].q;
                if(sum+x.a<=m) {
                    sum+=x.a;
                    ans++;
                    q.push(x.a);
                }
                else if(!q.empty() && q.top()>x.a){
                    int y=q.top();q.pop();q.push(x.a);
                    sum=sum-y+x.a;
                }       
            }
            else if(sum+data[i].a<=m) {
                sum+=data[i].a;
                q.push(data[i].a);
                ans++;
            }
            else if(!q.empty() && q.top()>data[i].a){
                int y=q.top();q.pop();q.push(data[i].a);
                sum=sum-y+data[i].a;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40448823/article/details/81488195
今日推荐