CodeForces - 1315D Recommendations (贪心+multiset)
一开始的想法是让物品按数量从小到大或者从大到小贪心,然而怎么想都不对,最后发现应该按价格贪
首先求出最终的物品数量序列(扫一遍即可)
然后把所有物品按价格从大到小排序,每次选价格最大的去匹配尽量小的数量(必须大于等于原来的数量),用multiset实现即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=2e5+10,mod=1e9+7,inf=0x3f3f3f3f; 5 int n,a[N]; 6 struct D {int a,b;} d[N]; 7 bool cmp1(const D& x,const D& y) {return x.a<y.a;} 8 bool cmp2(const D& x,const D& y) {return x.b>y.b;} 9 multiset<int> st; 10 ll solve() { 11 ll ret=0; 12 for(int i=1; i<=n; ++i)st.insert(a[i]); 13 sort(d+1,d+1+n,cmp2); 14 for(int i=1; i<=n; ++i) { 15 auto x=st.lower_bound(d[i].a); 16 ret+=(ll)(*x-d[i].a)*d[i].b; 17 st.erase(x); 18 } 19 return ret; 20 } 21 int main() { 22 scanf("%d",&n); 23 for(int i=1; i<=n; ++i)scanf("%d",&d[i].a); 24 for(int i=1; i<=n; ++i)scanf("%d",&d[i].b); 25 sort(d+1,d+1+n,cmp1); 26 for(int i=1; i<=n; ++i)a[i]=max(a[i-1]+1,d[i].a); 27 printf("%lld\n",solve()); 28 return 0; 29 }