[ABC376E] Max × Sum

[ABC376E] Max × Sum

题意

给出 \(A_1,A_2,\cdots,A_N\)\(B_1,B_2,\cdots,B_N\)

\(S\)\(\lbrace1, 2, \dots, N\rbrace\) 的一个大小为 \(K\) 的子集,问该表达式的最小值:

\[\displaystyle \left(\max_{i \in S} A_i\right) \times \left(\sum_{i \in S} B_i\right) \]

思路

可以发现 \(\max_{i\in S} A_i\) 最多只有 \(N\) 种取值,于是可以将 \(A,B\) 按照 \(A_i\) 升序排序,设 \(x\)\(S\) 中的最大数字,则问题可以转换成求以下表达式的最小值:

\[A_x\times \left(\sum_{i \in S} B_i\right) \]

这时再枚举 \(x\),则只需要最小化 \(\sum_{i \in S} B_i\)。因为选了 \(A_x\),所以 \(B_x\) 一定被选,剩下的 \(B_i\) 则取前 \((x-1)\) 项的前 \((K-1)\) 小值,该过程可以使用 multiset 维护。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int T,n,k,ans;
struct node{
	int x,y;
}a[2000005];
bool cmp(node x,node y){
	return x.x<y.x;
}
multiset<int> bg;
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(),cout.tie();
	cin>>T;
	while(T--){
		bg.clear(),ans=LONG_LONG_MAX;
		cin>>n>>k;
		for(int i=1;i<=n;i++)
			cin>>a[i].x;
		for(int i=1;i<=n;i++)
			cin>>a[i].y;
		sort(a+1,a+1+n,cmp);
		int nw=0;
		for(int i=1;i<k;i++)
			bg.insert(a[i].y),nw+=a[i].y;
		for(int i=k;i<=n;i++){
			ans=min(ans,(nw+a[i].y)*a[i].x);
			if(k!=1){//k=1时multiset为空,于是喜提RE
				if(a[i].y<*--bg.end()){//比前k-1小的最大值还小
					nw-=*--bg.end();
					bg.erase(--bg.end());
					nw+=a[i].y;
					bg.insert(a[i].y);
				}
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}
posted @ 2025-03-26 10:58  WuMin4  阅读(17)  评论(0)    收藏  举报