[CF1379C] Choosing flowers - 貪心,二分,排序
阿新 • • 發佈:2020-07-20
Description
有 \(m\) 種物品,每種物品第一次買價值為 \(a_i\),以後每次買都是 \(b_i\)。求買 \(n\) 件物品的最大總價值。\(n \le 10^9, m \le 10^5\)
Solution
容易證明,最多隻重複拿一種花,一定不會更劣
假設所有花已經按照 \(a\) 降序排列
設這種花是第 \(i\) 種,則所有被單次選擇的 \(j\) 一定滿足 \(a_j > b_i\)(等號可取可不取)
故只需求出滿足 $a_j > b_i $ 的 \(a_j\) 中前(不超過) \(k-1\) 大的和
在字首和序列上二分實現,注意如果二分出的選段 \([1,pos]\)
#include <bits/stdc++.h> using namespace std; #define int long long const int N = 1000005; struct pr { int a,b; bool operator < (const pr &x) { return a > x.a; } } s[N]; int n,m,a[N],b[N],c[N],d[N]; void solve() { cin>>n>>m; for(int i=0;i<=m+2;i++) a[i]=b[i]=c[i]=d[i]=0; for(int i=1;i<=m;i++) cin>>s[i].a>>s[i].b; sort(s+1,s+m+1); for(int i=1;i<=m;i++) a[i]=s[i].a, b[i]=s[i].b, d[i]=-a[i]; for(int i=1;i<=m;i++) c[i]=c[i-1]+a[i]; int ans=0; for(int i=1;i<=m;i++) { int pos=lower_bound(d+1,d+m+1,-b[i])-d-1; pos=min(pos,n-1); if(i<=pos && pos<n-1 && pos<m && a[pos+1]>b[i]) ++pos; int tmp=c[pos], fg=0; if(i<=pos) tmp-=a[i], fg=1; tmp+=a[i]+b[i]*(n-1-pos+fg); ans=max(ans,tmp); } cout<<ans<<endl; } signed main() { ios::sync_with_stdio(false); int t; cin>>t; while(t--) solve(); }