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 }

 

posted @ 2020-03-01 17:26  jrltx  阅读(289)  评论(0编辑  收藏  举报