*题解: CF2229F Load Unbalancing

题目链接

解析

看到数据范围先想到状压 dp,设 \(f_{S}\) 为已添加元素集合为 \(S\) 时,\(b\) 中元素最大值。然而,这个状态并不具有最优子结构,\(S\) 的最优情况不能从 \(S\) 的子集的最有情况转移得到,所以还是回去找性质吧。

考虑 \(\max(b)\) 的组成,猜想其必定可以在最后加入 \(\max(a)\) 得到。也就是说在加入最后一个元素前\(\min(b) + \max(a) \ge \max(b)\)

假设在加入最后一个元素前 \(\min(b) + \max(a) < \max(b)\),考虑此时 \(\max(b)\) 的构成。设 \(\max(b)\) 去掉最后添加的元素 \(x\) 后变为 \(y\),那么由于每次操作会将元素加到 \(b\) 的最小值,所以应当有 \(y \le \min(b)\)。又因为 \(x \le \max(a)\),故 \(x + y = \max(b) \le \min(b) + \max(a)\),矛盾。

这样,去掉一个 \(\max(a)\),问题转化为求 \(\min(b)\) 的最大值。考虑二分答案 \(x\),现在要判断能否构造出 \(\min(b) \ge x\) 的方案。有一个必要条件是 \(a\) 能至少分出 \(k\) 组数,每组里面的数的和大于等于 \(x\)。事实上这也是充分的,将分出来的 \(k\) 组数一一对应 \(b\) 中的 \(k\) 个位置,要在哪个位置上加就在对应那组中取出一个数加上。

判断能否分组可以使用状压 dp。设 \(f_S\) 表示已经分出来了的元素集合为 \(S\),最多分出多少组;\(g_S\) 表示 \(f_S\) 最大的情况下,新的元素和小于 \(x\) 的一组中元素最大和。转移比较常规。

时间复杂度 \(O(2^n \cdot n \log V)\)

代码

注意开 long long。

/*
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 18,M = 10 + 5,L = 19,L2 = 17,mod = 998244353;
int a[N + 5];
ll f[(1 << N) + 3][2];
int n,k;
bool chk(ll x){
	int m = n - 1;
	for(int i=0;i < (1 << m);i++){
		f[i][0] = f[i][1] = 0;
	}
	for(int i=0;i < (1 << m);i++){
		for(int j=0;j<m;j++){
			if(!(i & (1 << j))){
				int ni = i | (1 << j);
				ll f0 = f[i][0],f1 = f[i][1] + a[j + 1];
				if(f1 >= x){
					f0++;
					f1 = 0;
				}
				if(f[ni][0] < f0){
					f[ni][0] = f0;
					f[ni][1] = f1;
				}else if(f[ni][0] == f0 && f[ni][1] < f1){
					f[ni][1] = f1;
				}
			}
		}
	}
	return f[(1 << m) - 1][0] >= k;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	int T;
	cin>>T;
	while(T--){
		
		cin>>n>>k;
		ll sum = 0;
		
		for(int i=1;i<=n;i++){
			cin>>a[i];
			sum += a[i];
		}
		sort(a + 1,a + n + 1);
		ll l = 0,r = sum - a[n];
		while(l < r){
			ll mid = (l + r + 1) >> 1;
			if(chk(mid)){
				l = mid;
			}else{
				r = mid - 1;
			}
		}
		cout<<r + a[n]<<'\n';
	}
	return 0;
}

posted @ 2026-05-27 17:25  yutar  阅读(20)  评论(0)    收藏  举报