餐馆(顾客选择)问题

餐馆

牛客网:餐馆
题目描述
某餐馆有n张桌子,每张桌子有一个参数:a 可容纳的最大人数; 有m批客人,每批客人有两个参数:b人数,c预计消费金额。 在不允许拼桌的情况下,请实现一个算法选择其中一部分客人,使得总预计消费金额最大

输入描述:
输入包括m+2行。 第一行两个整数n(1 <= n <= 50000),m(1 <= m <= 50000) 第二行为n个参数a,即每个桌子可容纳的最大人数,以空格分隔,范围均在32位int范围内。 接下来m行,每行两个参数b,c。分别表示第i批客人的人数和预计消费金额,以空格分隔,范围均在32位int范围内。

输出描述:
输出一个整数,表示最大的总预计消费金额

输入:
3 5
2 4 2
1 3
3 5
3 7
5 9
1 10
输出:
20

思路:
因为人数不能超过一张桌子的容量,而且又想消费额最大,所以自然想到了贪心。
而贪心又有不同的解决技巧:

  1. 对桌子进行升序排序,同时对顾客消费额进行降序排列。先从消费额最大的开始,找这批顾客在原来排序后的桌子中“所需要合适容量的桌子”,用到了python中的bisect库函数,这里用的是bisect_left。 如果所有的桌子都不合适,就跳过这批顾客。如果能找到,那就删除掉这张桌子,并统计上消费金额。直至所有的顾客都遍历完为止。两次排序,一次遍历,还有库函数的二分查找,总的复杂度就是log(N)。
import bisect
n,m = [int(x) for x in input().split()]
a = [int(x) for x in input().split()]
A = []
for i in range(m):
    A.append([int(x) for x in input().split()])
a.sort()
A.sort(key=lambda x:x[1], reverse=True)
counter = 0
for i in A:
    index = bisect.bisect_left(a,i[0])
    if index != len(a):
        counter += i[1]
        del a[index]
print(counter)
  1. 还是贪心算法,所不同的是这次是把桌子和顾客人数都按照升序排列。然后外层遍历桌子,内层遍历顾客。目的是为每一个桌子找最合适的顾客。最合适的选择:在顾客容量不大于桌子的前提下寻找消费金额最大的,所以需要用到一个temp存储当前桌子适合的顾客批次,从中选择最大的金额。统计上即可!这个方法后面超时了。。。
链接:https://www.nowcoder.com/questionTerminal/d2cced737eb54a3aa550f53bb3cc19d0?f=discussion
来源:牛客网

n,m=[int(x) for x in input().split()] #在m批客人中选择n批上n个桌子
table=[int(x) for x in input().split()] #每个桌子可容纳的最大人数
cus=[[int(x) for x in input().split()] for i in range(m)] #分别表示第i批客人的人数和预计消费金额
 
table.sort()#将桌子按可容纳人数从小到大排列
cus=sorted(cus,key=lambda x:x[0])#按每批顾客的人数进行从小到大排序
money=0#总金额
 
for i in range(n):
    temp=[]#盛放第i个桌子可接受的顾客批j
    for j in range(len(cus)): #注意range中要用cus的length时时更新
        if cus[j][0]>table[i]:
            break
        temp.append(cus[j])
    temp=sorted(temp,key=lambda x: x[1])#按消费金额排序
    if temp:
        money+=temp[-1][1]
        cus.remove(temp[-1])#此批客人已就坐
 
print(money)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值