20200903纪念品笔试题

题目描述:
李华顺利到达了巴黎,李华遇到了许多心动的纪念品想带回家,但是他又不想自己太累,而且他买纪念品也有相应的预算k,
现给出他心动的纪念品清单:总共n件,其中每件都各有其价格price,重量weight,心动值v(1-5),需要注意在心动值不同的情况下,
李华优先选心动值大的纪念品,若心动值相同,李华会优先选择比较便宜的纪念品,具体见样例。同时给出李华在保证不累的情况下,
最多能拿的物品重量m,在不超过预算并且保证不累的情况下,李华最多可以带几件纪念品回家?

输入描述:
第一行三个正整数,分别为:纪念品件数n,最多能拿物品重量m,预算k。
第二行到n+1行,分别为物品价格price,重量weight,心动值v:

输出描述
在不超过预算并且保证不累的情况下,李华最多可以带回家的纪念品 件数

样例输入(为了方便看,已经按照后前中排好序)

4 11 1000
600 5 3
100 2 2
300 5 2
50 1 1

样例输出

3

由于李华会有限选择心动值大的物品,所以李华选择了第一件和第三件物品

方法一是对二维数组的心动值和价格进行排序,之后从上往下依次累加进背包就可以
方法二是对二维数组的心动值进行排序,之后拿心动值高的,然后心动值一样就拿价格低的
解题思路:注意注意注意!此题区别于背包问题。这个题是选心动值优先,若心动值相同,优先选择比较便宜的纪念品,若价格相同,优先选择轻的。(心动值优先,答案为2,装两个心动值600 5 3,100 2 2的物品,第三个物品因为重量是5装不下了,所以只能装前两个,则心动值之和为3+2=5)解题方法为将物品按照将心动值由大到小逆序排序,再将价格由小到大正序排序,最后将价格由小到大排序(索引为后前中)。在满足钱够和背包能装下的前提下买心动值大的物品

而背包问题是找到最优解让心动值的和最大,而不是心动值优先。如果按照此题,应该装600 5 3,100 2 2和50 1 1答案应该为3,心动值优先不会绕过大的心动值去选小的心动值。

import sys
import numpy as np

a = sys.stdin.readline().strip().split()
list1 = []

for i in range(int(a[0])):
    tem = []
    val = sys.stdin.readline().strip().split()
    # for循环将值存入数组,注意此处存入必须为int型,要不然np.lexsort不能处理字符串
    for j in val:
        tem.append(int(j))
    list1.append(tem)  
    
list2 = np.array(list1) # 转化为array对象
index1 = np.lexsort([list2[:,1],list2[:,0],-1*list2[:,2]])   # 注意此处排序后是索引排序,关键词从后向前排序
data_list2 = list2[index1]

money = 0
weight = 0
number = 0
for n in data_list2:
    if (money + n[0]) <= int(a[2]) and weight + n[1] <= int(a[1]):  # 满足两者才能获得
        money += n[0]
        weight += n[1]
        number += 1
    else:
        print(number)  # 此题答案
print(number)  # 程序走完的答案
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值