问题描述: 蒜厂幼儿园有n 个小朋友,每个小朋友都有自己想玩的玩具。身为幼儿园园长的你决定给幼儿园买一批玩具,由于经费有限,你只能买m 个玩具。已知玩具商店一共卖k 种玩具,编号为1,2,3,…k,你让每个小朋友把想玩的玩具编号都写在了纸上。你希望满足尽可能多的小朋友的需求,请计算出最多能满足多少个小朋友的玩具需求。
输入格式 第一行,输入三个整数n,m,k(1≤n≤100,1≤m≤k≤15)中间用空格分开。
接下来n 行,第i+1(0≤i<n) 行的第一个数字 a i a_i ai 代表第 i 个小朋友想玩的玩具数量,接下来有 a i a_i ai 个数字,代表这 a i a_i ai 个玩具的编号。
输出格式 输出一个整数,表示最多能满足多少小朋友的玩具需求。
样例输入
5 3 5
2 1 4
0
2 3 1
3 2 3 4
2 4 5
样例输出
3
思路
- 二进制枚举所有状态
- 记录每次状态购买玩具数和具体购买的情况(布尔数组实现)
- 当状态的购买数等于实际购买数时展开检查
- 检查满足了多少孩子的需求进而找出最值
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func maxChild(child_toy [][]int, m int, k int) int {
res := 0
toy_buy := make([]bool, k+1) // 某状态下已买玩具情况用布尔数组表示
toy_num := 0 // 某状态下已买玩具数目
for i := 0; i < 1<<k; i++ {
toy_buy = make([]bool, k+1)
toy_num = 0
for j := 0; j < k; j++ {
if i&(1<<j) > 0 {
toy_buy[j+1] = true
toy_num++
}
}
// 如果当前状态假设购买玩具数与实际购买玩具数相符合则展开检查
if toy_num == m {
child_num := 0
for row := 0; row < len(child_toy); row++ {
flag := true // 标记是否满足孩子需求
// 首数值代表该孩子玩具需求数
for col := 1; col <= child_toy[row][0]; col++ {
if !toy_buy[child_toy[row][col]] { // 任意一个需求未满足则代表不符合需求
flag = false
break
}
}
if flag {
child_num++
}
}
if res < child_num { // 更新最大满足孩子数
res = child_num
}
}
}
return res
}
func main() {
var n, m, k int
fmt.Scanf("%d %d %d\n", &n, &m, &k)
child_toy := make([][]int, n)
for i, _ := range child_toy {
child_toy[i] = make([]int, k+1)
}
// 考虑到输入的稳定性采用bufio标准输入库
sca := bufio.NewScanner(os.Stdin)
for i := 0; i < n; i++ {
if sca.Scan() {
lineNums := strings.Split(sca.Text(), " ")
for j := 0; j < len(lineNums); j++ {
child_toy[i][j], _ = strconv.Atoi(lineNums[j])
}
}
}
// fmt.Println(child_toy)
fmt.Println(maxChild(child_toy, m, k))
}