题解:蓝桥云课 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
posted @ 2026-03-04 15:19  团爸讲算法  阅读(0)  评论(0)    收藏  举报