既然选择了远方,便只顾风雨兼行|

H_W_Y

园龄:1年11个月粉丝:28关注:15

2023-07-07 15:57阅读: 17评论: 0推荐: 0

[P6093 [JSOI2015] 套娃]题解-贪心+set

20230707
不想做题于是随机跳题
传送门

我们考虑每个套娃i套到另一个套娃j里面的价值
很明显可以知道,这样可以减少b[j]out[i]
为了让答案尽可能小
我们就要让每一个套娃被套进去的价值最大
而我们并不能改变out[i]
所以只要把它套到最大的b[j]中即可

再来换一个角度,考虑对于每一个j
我们想要找到能被我套进去的out[i]最大的i

为了同时满足这两个条件
首先我们按照b的大小从大到小排序
每一次再去找小于in[i]的最大的out[j]
ans减去这种操作带来的贡献ou[j]b[i]即可
而维护是可以用set来进行

#include <bits/stdc++.h>
using namespace std;
#define ll long long

const int maxn=2e5+10;
int n;
ll ans=0;
struct node{
  int out,in,b;
  bool operator < (const node &rhs)const{
  	if(b!=rhs.b) return b>rhs.b;
  	return out>rhs.out;
  }
}a[maxn];

multiset<int> st;
int read(){
  int x=0,f=1;char ch=getchar();
  while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
  while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  return x*f;
}

int main(){
  /*2023.7.7 H_W_Y P6093 [JSOI2015] 套娃 贪心+set*/ 
  n=read();
  for(int i=1;i<=n;i++){
  	a[i].out=read();a[i].in=read();a[i].b=read();
  	st.insert(a[i].out);ans+=1ll*a[i].in*a[i].b;
  }
  sort(a+1,a+n+1);
  for(int i=1;i<=n;i++){
  	multiset<int>::iterator it=st.lower_bound(a[i].in);
  	if(it!=st.begin()) ans-=1ll* (*--it)*a[i].b,st.erase(it);
  }
  printf("%lld\n",ans);
  return 0;
}

总结:
在贪心算法中经常会需要出现类似找出并删除最小的大于等于某个值的元素
这种操作能轻松地通过 set 来完成。

本文作者:H_W_Y

本文链接:https://www.cnblogs.com/H-W-Y/p/17535244.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   H_W_Y  阅读(17)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起