At376 E - Max × Sum
E.Max × Sum
题意简述
给定两个长为n的序列,求\(A = (A_1, A_2, \dots, A_N)\) 和 \(B = (B_1, B_2, \dots, B_N)\).
让 \(S\) 成为一个长为 \(K\) 的子序列 \(\lbrace1, 2, \dots, N\rbrace\) . 请找到以下值的最小可能
\(\displaystyle \left(\max_{i \in S} A_i\right) \times \left(\sum_{i \in S} B_i\right).\)
解题思路
考虑朴素的枚举思路,直接枚举S的子集有 \(2^k\) 种可能,肯定不优,选择最大值进行枚举,那么从小到大枚举每种可能的最大值,以及当前最大值对应最小可能的\(\displaystyle \left(\sum_{i \in S} B_i\right).\)考虑用priority_queue
维护不难得到以下思路
1.按a的值从小到大排序,从最小可能的最大值开始枚举每个最大值
2.用一个变量记录每个最大值对应的最小可能的\(\displaystyle \left(\sum_{i \in S} B_i\right).\)
3.从当前遍历到的最大值转移到下一个可能的最大值就是删掉前k个数中最大的一个,在把当前遍历到的数添加进去。
AC code
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const ll inf=1e18;
void solve(){
int n,m;cin>>n>>m;
vector<pair<ll,ll> >a(n+1);
for(int i=1;i<=n;i++) cin>>a[i].first;
for(int i=1;i<=n;i++) cin>>a[i].second;
sort(a.begin()+1,a.end());
ll ans=LLONG_MAX;
priority_queue<ll>Q;
ll sum=0;
for(int i=1;i<=m-1;i++){
Q.push(a[i].second);
sum+=a[i].second;
}
for(int i=m;i<=n;i++){
sum+=a[i].second;
ans=min(ans,sum*a[i].first);
Q.push(a[i].second);
sum-=Q.top();
Q.pop();
}
cout<<ans<<endl;
}
int main(){
cin.tie(0)->ios::sync_with_stdio(false);
int T=1;cin>>T;
while(T--) solve();
return 0;
}

浙公网安备 33010602011771号