3. 题目
租书屋老板打算购一批新书,选了n本价格相同的书作为备选,并给VIP读者发了一批调查问卷,收集到每位读者想看的书的列表。为了节省采购成本,老板决定在保证每位VIP读者至少有一本喜欢的书进入采购清单的前提下,最小化采购费用。现把书和读者都从0开始编号,整理出读者想看的书的列表为b,请输出最少的采购书本数量。
输入描述:
第一行为书本数,第二行为读者数;第三行开始为读者想看的书的列表b,每行至少包含一本书的id,多本书的id用1个空格分隔。注意:
- 题目保证输入的合法性
- 1 <= n <= 100
- 1 <= b.length <= 20 (即最多20个读者)
- 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)))