题目传送门

右侧可以传送到原题位置。

题目大意

题目描述

由于 KEYENCE 总部的员工越来越多,他们决定将总部各部门分成两组,错开午休时间。

KEYENCE 总部有 N N N 个部门,第 i i i 个部门 ( 1 ≤ i ≤ N ) (1\leq i\leq N) (1iN) 的人数为 K i K_i Ki

将每个部门分配到 A A A 组或 B B B 组,让每个组里面的所有人在同一时间午休,并确保 A A A 组和 B B B 组的午休时间不重叠,求同一时间午休的最大人数的最小值。
换句话说,求分配给 A A A 组的部门总人数和分配给 B B B 组的部门总人数中较大者的最小值。

数据范围

  • 2 ≤ N ≤ 20 2 \leq N \leq 20 2N20
  • 1 ≤ K i ≤ 1 0 8 1 \leq K_i \leq 10^8 1Ki108
  • 所有输入值均为整数。

解题思路

注意到数据范围比较小,可以考虑爆搜。

对于每个部门的人数 K i K_i Ki,由于这 K i K_i Ki 个人只能同时在 A 组或者同时在 B 组,所以每个部门都只有两种决策:

  • 将所有人划分在 A 组中。
  • 将所有人划分在 B 组中。

因此,我们使用 dfs 进行枚举,分别考虑第 i i i 个部门划分在 A 组与 B 组的情况。记 P A , P B P_A,P_B PA,PB 分别为 A 组人数与 B 组人数,那么 a n s = max ⁡ { a n s , min ⁡ { P A , P B } } ans = \max\{ans,\min\{P_A,P_B\}\} ans=max{ans,min{PA,PB}},其中 a n s ans ans 代表答案。

算法总时间复杂度为 O ( 2 n ) \mathcal{O}(2^n) O(2n)

CODE:

#include <bits/stdc++.h>
using namespace std;
#define int long long
int k[30], ans = 1e18, n;
inline void dfs(int step, int P_A, int P_B) { //正在遍历部门 step,A 组人数为 P_A,B 组人数为 P_B 
	if (step == n + 1) {
		ans = min(ans, max(P_A, P_B));
		return;
	}
	dfs(step + 1, P_A + k[step], P_B); 
	dfs(step + 1, P_A, P_B + k[step]);
}
signed main() {
	ios::sync_with_stdio(false);
	ios_base::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> k[i];
	dfs(1, 0, 0);
	cout << ans;
	return 0;
}
Logo

欢迎加入西安开发者社区!我们致力于为西安地区的开发者提供学习、合作和成长的机会。参与我们的活动,与专家分享最新技术趋势,解决挑战,探索创新。加入我们,共同打造技术社区!

更多推荐