题解:蓝桥云课 2942 数字王国之军训排队
【题目来源】
蓝桥云课:1.数字王国之军训排队 - 蓝桥云课 (lanqiao.cn)
【题目描述】
数字王国开学了,它们也和我们人类一样有开学前的军训,现在一共有 \(n\) 名学生,每个学生有自己的一个名字 \(a_i\) (数字王国里的名字就是一个正整数,注意学生们可能出现重名的情况),此时叛逆教官来看了之后感觉十分别扭,决定将学生重新分队。
排队规则为:将学生分成若干队,每队里面至少一个学生,且每队里面学生的名字不能出现倍数关系(注意名字相同也算是倍数关系)
现在请你帮忙算算最少可以分成几队?
例:有 \(4\) 名学生\((2,3,4,4)\),最少可以分成\((2,3)\)、\((4)\)、\((4)\)共 \(3\) 队。
【输入】
第一行包含一个正整数 \(n\),表示学生数量。
第二行包含 \(n\) 个由空格隔开的整数,第 \(i\) 个整数表示第 \(i\) 个学生的名字 \(a_i\)。
【输出】
输出共 \(1\) 行,包含一个整数,表示最少可以分成几队。
【输入样例】
4
2 3 4 4
【输出样例】
3
【算法标签】
《蓝桥云课 2942 数字国王之军训排队》 #思维# #搜索# #DFS#
【代码详解】
def check(x, group):
#判断学生x能否加入group中
for y in group:
if x % y == 0 or y % x == 0:
return False
return True
def dfs(depth):
#最优性剪枝
global ans
#如果当前分组状态已经比ans大,则当前分组策略肯定不行
if len(Groups)>ans:
return
#depth:当前是第几个学生
#递归出口
if depth == n:
ans = min(ans, len(Groups))
return
#对于每个学生,枚举该学生放在哪一组
for every_group in Groups:
#当前第depth个学生能否加入当前组every_group
#可行性剪枝
if check(a[depth], every_group):
every_group.append(a[depth])
dfs(depth+1)
every_group.pop()
#对于每个学生,也可以单独作为一组
Groups.append([a[depth]])
dfs(depth + 1)
Groups.pop()
n = int(input())
a = list(map(int, input().split()))
#Group表示分组情况,每个元素表示一个组内的情况
Groups = []
ans = n
dfs(0)
print(ans)
【运行结果】
4
2 3 4 4
3
浙公网安备 33010602011771号