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;
}
posted @ 2025-05-23 20:19  usedchang  阅读(14)  评论(0)    收藏  举报