zoukankan      html  css  js  c++  java
  • BZOJ4482[Jsoi2015]套娃——贪心+set

    题目描述

    【故事背景】
    刚从俄罗斯旅游回来的JYY买了很多很多好看的套娃作为纪念品!比如右
    图就是一套他最喜欢的套娃J。JYY由于太过激动,把所有的套娃全
    部都打开了。而由于很多套娃长得过于相像,JYY现在不知道该如何把它们装
    回去了(他实在搞不清,应该把哪个套娃装到哪个里面去了)。
    JYY一共有N个拆开的套娃,每个套娃从1到N编号。编号为i的套娃有一个外径Outi和一个内径Ini(Ini<Outi)。
    对于套娃i和套娃j,如果满足Outi<INj,那么套娃i就可以装到套娃j里面去。
    注意,一个套娃内部,不允许并排的放入多个套娃。
    也就是说,如果我们将i装到j的内部之后,还存在另一个套娃k,也满足Outk<Inj,我们此时是不允许再将k放
    到j内部的(因为j的内部已经放入了i)。但是,如果k还满足Outk<Ini,那么我们允许先将k放到i的内部,
    然后再把k和i作为一个整体放入j的内部。
    JYY认为一套好的套娃,内部的空隙一定是尽量少的。如果套娃j内部装入了套娃i,那么我们认为,套娃j内部
    产生的空隙为Inj-Outi;如果套娃j的内部什么也没有装,那么套娃j的空隙则就是Inj。
    JYY也希望,那些长得更加好看的套娃,里面可以填的尽量满一些;而相对
    那些不那么好看的套娃,JYY也就相对不那么介意一些。为此JYY对于编号为
    i的套娃设置了一个好看度Bi,如果这个套娃内部还存在K的空隙,那么JYY对
    于这个套娃就会产生K*Bi的不满意度。
    JYY对于一个套娃安装方案的不满意度,就是每个套娃产生的不满意度的总
    和。JYY希望找出一个,不满意度最小的套娃安装方案。

    输入

    第一行包含一个正整数N。接下来N行,每行包含三个正整数Outi,Ini,Bi,表示i号套娃的外径,内径,以及好看度。N<=2∗10^5,1<=Ini<Outi<=10^4,1<=Bi<=10^9

    输出

    输出文件包含一行一个整数,表示不满意度的最小值

    样例输入

    3
    5 4 1
    4 2 2
    3 2 1

    样例输出

    7
     
    我们先将所有的$k_{i}$加入答案,即$ans=sumlimits_{i=1}^{n}in_{i}*b_{i}$。
    现在考虑将$i,j$两个套娃合并,即将$i$放入$j$中的贡献:答案会减少$out_{i}*b_{j}$。
    显然对于每个套娃,我们一定会将外径小于它的内径中最大的与他合并。
    那么我们贪心地将$b_{i}$从大到小排序,枚举套娃,每次选择当前套娃能装下的最大的进行合并。
    可以证明对于$b_{i}>b_{j},out_{k}>out_{l}$且保证$k,l$均能与$i,j$合并时,$b_{i}*out_{k}+b_{j}*out_{l}>b_{i}*out_{l}+b_{j}*out_{k}$。
    用$multiset$保存当前剩下的套娃即可。
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<bitset>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    using namespace std;
    struct miku
    {
    	int in,out,b;
    }a[200010];
    multiset<int>s;
    multiset<int>::iterator it;
    int n;
    ll ans;
    bool cmp(miku a,miku b)
    {
    	return a.b>b.b;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d%d%d",&a[i].out,&a[i].in,&a[i].b);
    		ans+=1ll*a[i].in*a[i].b;
    		s.insert(a[i].out);
    	}
    	sort(a+1,a+1+n,cmp);
    	for(int i=1;i<=n;i++)
    	{
    		it=s.lower_bound(a[i].in);
    		if(it!=s.begin())
    		{
    			it--;
    			ans-=1ll*a[i].b*(*it);
    			s.erase(it);
    		}
    	}
    	printf("%lld",ans);
    }
  • 相关阅读:
    项目一:CRM(客户关系管理系统)--1
    数据库统一API--SQLAlchemy
    消息队列--1--Redis
    消息队列--2--RabbitMQ
    python之路--web--2--Django-11-信号
    python之路--web--2--Django-10--序列化
    python之路--web--2--Django-8-分页
    python之路--web--2--Django-6-Session
    python之路--web--2--Django-5-Cookie
    python之路--web--2--Django-7-跨站请求伪造
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/10461734.html
Copyright © 2011-2022 走看看