华为2020.05.13笔试题:03.最少采购几本书

3. 题目

租书屋老板打算购一批新书,选了n本价格相同的书作为备选,并给VIP读者发了一批调查问卷,收集到每位读者想看的书的列表。为了节省采购成本,老板决定在保证每位VIP读者至少有一本喜欢的书进入采购清单的前提下,最小化采购费用。现把书和读者都从0开始编号,整理出读者想看的书的列表为b,请输出最少的采购书本数量。

输入描述:

第一行为书本数,第二行为读者数;第三行开始为读者想看的书的列表b,每行至少包含一本书的id,多本书的id用1个空格分隔。注意:

  1. 题目保证输入的合法性
  2. 1 <= n <= 100
  3. 1 <= b.length <= 20 (即最多20个读者)
  4. 1 <= b[I].length <= n

输出描述:

最少的采购书本数量,前后不能有空格。

输入:

5
3
1 2
2
3 4

输出:

2

说明:5本书,3个读者,购买编号为2的书同时满足读者0和1; 购买编号为3或者4的书满足读者2; 最少的书本数量为2;

思路:

在这里插入图片描述

bn = int(input())  #书数目
pn = int(input())  #读者数
mix = [[0]*bn for _ in range(pn)]
# 将矩阵中,需要的书标记为1,不需要的标记为0
for i in range(pn):
    id = map(int, input().split())
    for j in id:
        mix[i][j] = 1
# print(mix)

def f(x, y):
    if len(x) == 1:
        return 1
    m = 0
    bn_i = 0
    for index in y:
        num = 0
        for i in x:
            if mix[i][index]:#统计这本书共有多少个人想要
                num += 1
            if num > m:      #找出哪本书想要的人最多,记录下书编号
                m = num
                bn_i = index
    y.remove(bn_i)  #除去最多人共有想要的书
    list1 = []
    for j in x:     #除去共同想要拥有此书的人
        if mix[j][bn_i]:
            list1.append(j) #存储想要此书的所有读者id
    x = list(set(x) -set(list1)) #去除想要此书的所有读者
    return f(x, y) + 1     #递归解法

print(f(list(range(pn)),list(range(bn))))
print(list(range(bn)))
print(list(range(pn)))
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值