Codeforces Round #523 (Div. 2) D. TV Shows
https://www.cnblogs.com/violet-acmer/p/10005351.html
•题意
有n个节目,每个节目都有个开始时间和结束时间。
定义 x,y 分别为租电视需要的花费和看电视需要的花费(应该是花的电费,哈哈)。
假如某电视节目的播放区间是[a,b],那么看完这个节目需要的总花费为x+(b-a)*y。
如果有其他节目的播放区间是[b,c],那么便不能和[a,b]的节目用同一个电视看。
求看完所有电视节目所需要的最少花费。
•题解
对于每个节目的播放区间[a,b],都会有个(b-a)*y 的花费;
能省钱的地方在“节目 i 是选择和之前的某个节目 j 共用一个电视,还是选择新租一个电视”;
这个只需要寻找一下有没有某个节目 j ,使得节目 i 和 j 共用一个电视要比 i 新租一个电视省钱。
(1):按节目开始时间从小到大排序,对于相同的开始时间,谁在前谁在后都可以。
(2):排序后,从第一个节目开始开始遍历。
假设来到第 i 个节目,查找节目 j,满足节目 j 的结束时间早于节目 i 的开始时间,并且节目 j 的结束时间尽可能晚;
判断节目 i 是否可以和节目 j 共用一个电视;
•贪心策略的证明(个人理解)
假设有①②③④节目,排好序后如下所示:
对于排序策略“相同的开始时间,谁在前谁在后都可以”的理解:
②③节目开始时间相同,假设 x > y,那么①②③节目的总花费有两种不同的策略,1.(①,②)+③ 和 2.(①,③)+②
方案1的总花费为 (x+(9-1)*y) + (x+(11-5)*y) = 2*x+14*y.
方案2的总花费为 (x+(11-1)*y) + (x+(9-5)*y) = 2*x+14*y.
显然,这两种方案所花费的价钱是相同的。
此题的难点在于“如何高效查找节目 j";
一开始本来打算开两个数组,一个数组存储节目的开始时间,一个数组存储节目的结束时间;
并用map存储结束时间相同的总节目数,然后,遍历的时候在结束时间的数组中二分查找;
实现了一下,又仔细想了想,感觉不行,还是太菜了。。。。。
没办法了,只好求助了,翻了翻大神博客,发现,差不多都用到了multiset这个容器,然后,补了补multiset;(tql)
•Code
- #include<iostream>
- #include<set>
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- #define ll __int64
- const int MOD=1e9+;
- const int maxn=1e5+;
- int n,x,y;
- int res;
- struct Node
- {
- int l,r;
- Node(int _a=,int _b=):l(_a),r(_b){}
- }show[maxn];
- multiset<int >_set;
- bool cmp(Node _a,Node _b)
- {
- return _a.l < _b.l;
- }
- int Solve()
- {
- sort(show+,show+n+,cmp);
- for(int i=;i <= n;++i)
- {
- multiset<int >::iterator it;
- it=_set.lower_bound(show[i].l);//二分查找
- //it=lower_bound(_set.begin(),_set.end(),show[i].l);
- if(it == _set.begin())//如果it == _set.begin(),说明 i 之前没有结束时间比其小的电视节目
- {
- res += x;
- res %= MOD;
- _set.insert(show[i].r);
- }
- else
- {
- it--;//当前的it指向的时间是第一个 >= show[i].l,所以,要it--才是最靠近show[i].l的结束时间
- ll cost=1ll*(show[i].l-*it)*y;
- if(cost <= x)
- {
- res += cost;
- _set.erase(it);
- }
- else
- res += x;
- res %= MOD;
- _set.insert(show[i].r);
- }
- }
- return res%MOD;
- }
- int main()
- {
- scanf("%d%d%d",&n,&x,&y);
- for(int i=;i <= n;++i)
- {
- int l,r;
- scanf("%d%d",&l,&r);
- show[i]=Node(l,r);
- res += 1ll*(r-l)*y%MOD;//记得加 1ll 防止爆int
- res %= MOD;
- }
- printf("%d\n",Solve());
- }
分割线:2019.7.2
•Code
- #include<bits/stdc++.h>
- using namespace std;
- #define ll long long
- const int MOD=1e9+;
- const int maxn=1e5+;
- int n;
- ll x,y;
- struct Data
- {
- int l,r;
- bool operator < (const Data &obj) const
- {
- return l < obj.l;
- }
- }tv[maxn];
- multiset<int >_set;
- multiset<int >::iterator it;
- ll Solve()
- {
- sort(tv+,tv+n+);
- ll ans=;
- for(int i=;i <= n;++i)///求出每个节目都需要一台电视的总花费
- ans=(ans+x+(tv[i].r-tv[i].l)*y)%MOD;
- _set.clear();
- for(int i=;i <= n;++i)
- {
- it=_set.lower_bound(tv[i].l);
- if(it != _set.begin())
- {
- --it;
- ll cur=(tv[i].l-*it)*y;
- if(cur <= x)///如果可以共用一台电视
- {
- ans=(ans+cur-x+MOD)%MOD;
- _set.erase(it);
- }
- }
- _set.insert(tv[i].r);
- }
- return ans%MOD;
- }
- int main()
- {
- // freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
- scanf("%d%lld%lld",&n,&x,&y);
- for(int i=;i <= n;++i)
- {
- int l,r;
- scanf("%d%d",&l,&r);
- tv[i]=Data{l,r};
- }
- printf("%lld\n",Solve());
- return ;
- }
Codeforces Round #523 (Div. 2) D. TV Shows的更多相关文章
- Codeforces Round #523 (Div. 2) D. TV Shows 模拟(多重集 先把所有区间加入多重集合)+贪心+二分
题意:给出n个电视节目的起始和结束时间 并且租一台电视需要x +y*(b-a) [a,b]为时段 问完整看完电视节目的最小花费是多少 思路:贪心的思想 情况1 如果新租一台电视的花费<=在空 ...
- Codeforces Round #523 (Div. 2)
Codeforces Round #523 (Div. 2) 题目一览表 来源 考察知识点 完成时间 A Coins cf 贪心(签到题) 2018.11.23 B Views Matter cf 思 ...
- Codeforces Round #523 (Div. 2) Solution
A. Coins Water. #include <bits/stdc++.h> using namespace std; int n, s; int main() { while (sc ...
- Codeforces Round #523 (Div. 2) E. Politics(最小费+思维建图)
https://codeforces.com/contest/1061/problem/E 题意 有n个点(<=500),标记第i个点的代价a[i],然后分别在这n个点建两棵树,对于每颗树的每个 ...
- Codeforces Round #523 (Div. 2) F. Katya and Segments Sets (交互题+思维)
https://codeforces.com/contest/1061/problem/F 题意 假设存在一颗完全k叉树(n<=1e5),允许你进行最多(n*60)次询问,然后输出这棵树的根,每 ...
- Codeforces Round #523 (Div. 2) Cdp
题:https://codeforces.com/contest/1061/problem/C 题意:给你一个序列,我们求他们子序列的个数,这个子序列有个限制就是每一个子序列上的值都必须是能整除他的下 ...
- Codeforces Round #523 (Div. 2) B Views Matter
传送门 https://www.cnblogs.com/violet-acmer/p/10005351.html 这是一道贪心题么???? 题意: 某展览馆展览一个物品,此物品有n堆,第 i 堆有a[ ...
- Codeforces Round #523 (Div. 2) C Multiplicity (DP)
传送门 https://www.cnblogs.com/violet-acmer/p/10005351.html 题意: 给定一数组a[],从a[ ]中除去任意个元素得到b[ ],求能形成多少“好序列 ...
- Codeforces Round #523 (Div. 2) C. Multiplicity
C. Multiplicity 题目链接:https://codeforc.es/contest/1061/problem/C 题意: 给出一串数,问它的“好序列“有多少.好序列的定义是,首先是一个子 ...
随机推荐
- LODOP用ADD_PRINT_IMAGE语句缩放打印图片
LODOP提高输出图片质量的方法:1.用ADD_PRINT_IMAGE语句打印图片,而且img元素的width和height属性要去掉或者设置足够大,这样就可以让下载引擎传给Lodop图片质量足够好; ...
- cookie中的小错误
今天在练习 cookie时意外的报了这个错. 这句话的意思是一个不识别的字符[32]出现在了cookie当中由于tomcat的版本比较高,所以在addCookie时是不能使用空格的 而在ASCII码中 ...
- Java 学习(1) ---JDK安装和配置环境变量
一,Java 开发的第一步,就是安装JDK(Java Development ToolKit Java开发工具包) JDK 是Java开发的核心,因为它包括Java 运行环境,工具包和命令.当我们安 ...
- 前端bug记录
记录一下前端入门时期遇到的一些bug. 1.同步.异步问题 背景:Javascript语言的执行环境是单线程.即一次只能完成一个任务.若有多个任务则需排队逐个执行——前一个任务完成,再执行后一个任务. ...
- 晨读笔记:CSS3选择器之属性选择器
一.属性选择器 1.E[foo^="bar"]:该属性选择器描述的是选择属性以bar开头的元素,如: //所有以名称g_开头的div的字体颜色为红色div[name^=" ...
- Civil 3D 二次开发 创建Civil 3D 对象—— 00 ——
本节中我们通过创建几何空间点.曲面和采样线了解Civil 3D对象的创建方法.因Civil 3D对象的创建方法相比AutoCAD对象创建要简单的多,比如创建一个几何空间点,最简单的情况采用一行代码(没 ...
- POJ 3580-SuperMemo-splay树
很完整的splay操作.做了这题就可以当板子用了. #include <cstdio> #include <algorithm> #include <cstring> ...
- Elasticsearch 删除数据
删除数据分为两种:一种是删除索引(数据和表结构同时删除,作用同SQLSERVER 中 DROP TABLE "表格名" ),另一种是删除数据(不删除表结构,作用同SQLSERVER ...
- Quartus prime 16.0 signaltap II 使用
前言 由于逻辑分析仪太贵,altera贴心提供signal tap II来观察输出波形,不过使能signaltap II会占用片内ram,毕竟原理就是把数据采样到ram中再通过jtag口上传到quar ...
- 【BZOJ1011】【HNOI2008】遥远的行星 误差分析
题目大意 给你\(n,b\),还有一个数列\(a\). 对于每个\(i\)求\(f_i=\sum_{j=1}^{bi}\frac{a_ja_i}{i-j}\). 绝对误差不超过\(5\%\)就算对. ...