求助 ABC F
  • 板块学术版
  • 楼主chlchl
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/7/29 21:48
  • 上次更新2023/11/3 06:59:43
查看原帖
求助 ABC F
363036
chlchl楼主2023/7/29 21:48

显然有贪心:每一类都按照 xx 从大到小排序。

思路是枚举选 ii 个 00 类物品,然后二分一个 kk,使得选 kk 个 22 类物品就可以把剩下还能选的 m−i−km-i-k 个 11 类物品全部撬开。

整个过程都用到了前缀和的优化。

时间复杂度 O(mlog⁡n)O(m\log n),但是 WA 了 9 个点,边界啥的我都注意到了,烦请大佬帮忙调调!!!!

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 2e5 + 10;
int n, m, la, lb, lc, a[N], b[N], c[N], sa[N], sb[N], sc[N];

bool cmp(int a, int b){
	return a > b;
}

bool check(int x, int len){
	return sc[x] >= min(lb, len - x);
}

main(){
	cin >> n >> m;
	for(int i=1,t,x;i<=n;i++){
		cin >> t >> x;
		if(t == 0)
			a[++la] = x;
		if(t == 1)
			b[++lb] = x;
		if(t == 2)
			c[++lc] = x;
	}
	sort(a + 1, a + 1 + la, cmp);
	sort(b + 1, b + 1 + lb, cmp);
	sort(c + 1, c + 1 + lc, cmp);
	for(int i=1;i<=la;i++)
		sa[i] = sa[i - 1] + a[i];
	for(int i=1;i<=lb;i++)
		sb[i] = sb[i - 1] + b[i];
	for(int i=1;i<=lc;i++)
		sc[i] = sc[i - 1] + c[i];
	int ans = 0;
	for(int i=0;i<=min(la,m);i++){
		int l = 0, r = min(lc, m - i), cnt = -1;
		while(l <= r){
			int mid = (l + r) >> 1;
			if(check(mid, m - i))
				cnt = mid, r = mid - 1;
			else
				l = mid + 1;
		}
		if(cnt == -1)
			continue;
//		cout << i << ' ' << ans + 
		int pos = min(lb, m - i - cnt);
		ans = max(ans, sa[i] + sb[max(0ll, pos)]);
	}
	printf("%lld\n", ans);
	return 0;
}
2023/7/29 21:48
加载中...