链接:https://www.nowcoder.com/acm/contest/86/I
来源:牛客网

题目描述

接下去,Sεlιнα(Selina) 又搞了个文艺竞演。
虽说是文艺竞演,其实只是为了满足 Sεlιнα 的内心企盼——看群男友献歌献舞。她排列好了各个参赛男友的节目顺序,然后将他们安排在两个舞台上表演,自己则在演播室里使用两台闭路电视同时观看。万万没想到的是,当一切准备就绪时,其中一台电视炸了,她不会修,也没有时间修。于是只能尴尬地使用一台闭路电视观看两个舞台上的节目。当然,这台电视不支持分屏同时观看,所以 Sεlιнα 只能不停地换台观看。现在,作为导演的 Sεlιнα 已经知道了两个舞台的节目 单以及每个节目 对于她所能产生的愉悦度 ,她想安排电视在每个时刻播放的频道(可以在某些时刻不看),使得自己能得到最大的愉悦度。现在请优秀的你告诉 Sεlιнα 最大能产生的愉悦度是多少。
要注意的是,文艺竞演没有广告插播,所以当一个节目结束时,另一个节目会立刻开始演出。 并且 Sεlιнα 看节目以分钟为单位,也就是说,她只能在每分钟结束的那一刻切换舞台。节目对 Sεlιнα 产生愉悦度是以分钟为单位的,也就是说,她看第 个节目每一分钟就会产生 的愉悦度。而 Sεlιнα 对节目的完整性丝毫不在意,没有完整地看一个节目是没有关系的。 

输入描述:

第一行三个数 ,表示舞台一有 个节目,舞台二有 个节目,总时长为 分钟。
接下去 行,每行两个整数 ,表示舞台一的第 个节目在第  分钟结束后开始,每分钟能产生愉悦度 。当一个节目开始时,这个舞台之前正在播放的节目直接停止,中间没有暂停。
接下去 行,每行两个整数 ,表示舞台二的第 个节目在第 分钟结束后开始,每分钟能产生愉悦度 。当一个节目开始时,这个舞台之前正在播放的节目直接停止,中间没有暂停。
数据保证每个舞台都有一个在 分钟时开始的节目(即最开始的节目),并且在同一个舞台中没有两个节目开始时间相同(即没有一个节目时长为 )。数据不保证输入中每个舞台的 会从小到大排序。 

输出描述:

输出共一行,一个整数,表示最大的愉悦度。

输入例子:
2 2 5
2 3
0 2
0 3
3 1
输出例子:
15

-->

示例1

输入

复制

2 2 5
2 3
0 2
0 3
3 1

输出

复制

15

说明

在这个样例中,Sεlιнα 在开始时观看频道二的节目,每分钟产生愉悦度 

 ;在第二分钟结束时刻切换到频道一,每分钟产生愉悦度 

 ,然后直到结束。总共产生愉悦度 

 。 
示例2

输入

复制

3 4 17
8 3
0 10
9 10
7 15
0 6
16 9
14 8

输出

复制

205

备注:



 
思路:
 
1. 将题目中的两个序列按照时间升序排列,然后合并在一个时间轴,在每个时间段内寻找获得效益最大的。  所以合并操作很容易想到 归并排序的思路
2. 使用 set ,离散化时间代替手写归并过程
【注】:题目中 可以有空闲时间段,因此 权值可能为负,所以 max3(0,a,b) 最小是0
 
方法一 AC 码:
 #include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector> using namespace std; #define max3(x, y, z) max(max((x), (y)), (z))
#define min3(x, y, z) min(mix((x), (y)), (z))
#define pb push_back
#define ppb pop_back
#define mk make_pair
#define pii pair<int, int>
#define pll pair<long long, long long> #define debug_l(a) cout << #a << " " << (a) << endl
#define debug_b(a) cout << #a << " " << (a) << " "
#define testin(filename) freopen((filename) ,"r",stdin)
#define testout(filename) freopen((filename) ,"w",stdout) #define close_sync (ios::sync_with_stdio(false)) typedef long long ll;
typedef unsigned long long ull; const double PI = 3.14159265358979323846264338327;
const double E = exp();
const double eps = 1e-; const int INF = 0x3f3f3f3f;
const int NINF = 0xc0c0c0c0;
// int maxn = 3e3 + 5;
// int MOD = 1e9 + 7; template <typename T>
void print_arr(T *arr, int arr_len)
{
for (int i = ; i < arr_len; i++)
cout << arr[i] << " ";
cout << endl;
} /*==================================begin=======================================*/ const int maxn = 1e5+;
struct Node {int x,v;};
Node f[maxn],s[maxn];
int cmp(Node n1, Node n2){
return n1.x<n2.x;
}
int main()
{
// testin("data.in");
close_sync;
int N,M,T;
cin>>N>>M>>T;
for(int i=;i<N;i++) cin>>f[i].x>>f[i].v;
for(int i=;i<M;i++) cin>>s[i].x>>s[i].v;
sort(f,f+N,cmp); sort(s,s+M,cmp); f[N].x=s[M].x=T; //关键,在遍历到数组最后一个元素的时候,下一个值是结束时间。从而计算权值 int i=,j=,t=,nt;
ll ans=;
while(i<N && j<M){
if(f[i].x<=t) i++;
if(s[j].x<=t) j++;
nt= min(f[i].x,s[j].x);
ans+=(nt-t)*max3(,f[i-].v,s[j-].v);
t=nt;
}
while(i<N){
if(f[i].x<=t) i++;
ans+=(f[i].x-t)*max3(,f[i-].v,s[j-].v);
t=f[i].x;
}
while(j<M){
if(s[j].x<=t) j++;
ans+=(s[j].x-t)*max3(,f[i-].v,s[j-].v);
t=s[j].x;
}
cout<<ans<<endl;
return ;
}
方法二 AC 码:
 #include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector> using namespace std; #define max3(x, y, z) max(max((x), (y)), (z))
#define min3(x, y, z) min(mix((x), (y)), (z))
#define pb push_back
#define ppb pop_back
#define mk make_pair
#define pii pair<int, int>
#define pll pair<long long, long long> #define debug_l(a) cout << #a << " " << (a) << endl
#define debug_b(a) cout << #a << " " << (a) << " "
#define testin(filename) freopen((filename) ,"r",stdin)
#define testout(filename) freopen((filename) ,"w",stdout) #define close_sync (ios::sync_with_stdio(false)) typedef long long ll;
typedef unsigned long long ull; const double PI = 3.14159265358979323846264338327;
const double E = exp();
const double eps = 1e-; const int INF = 0x3f3f3f3f;
const int NINF = 0xc0c0c0c0;
// int maxn = 3e3 + 5;
// int MOD = 1e9 + 7; template <typename T>
void print_arr(T *arr, int arr_len)
{
for (int i = ; i < arr_len; i++)
cout << arr[i] << " ";
cout << endl;
} /*==================================begin=======================================*/
const int maxn = 1e5+;
struct Node
{
int x,v;
}; Node f[maxn],s[maxn]; int cmp(Node n1, Node n2){
return n1.x<n2.x;
} void print_arr(Node a[],int n){
for(int i=;i<n;i++)
cout<<"("<<a[i].x<<","<<a[i].v<<")";
cout<<endl;
} int main()
{
//testin("data.in");
close_sync;
int N,M,T;
cin>>N>>M>>T;
for(int i=;i<N;i++) cin>>f[i].x>>f[i].v;
for(int i=;i<M;i++) cin>>s[i].x>>s[i].v;
sort(f,f+N,cmp); sort(s,s+M,cmp); // print_arr(f,N);print_arr(s,M); set<int> ss;
for(int i=;i<N;i++) ss.insert(f[i].x);
for(int i=;i<M;i++) ss.insert(s[i].x);
ss.insert(T); // for(set<int>::iterator it=ss.begin();it!=ss.end();++it)
// cout<<*it<<" ";
// cout<<endl; f[N].x=T;f[N].v=f[N-].v;
s[M].x=T;s[M].v=s[M-].v; set<int>::iterator it=ss.begin();
ll ans=;
for(int i=,j=,t=;t<T;){
while(i+<N+ && f[i+].x<=t) i++;
while(j+<M+ && s[j+].x<=t) j++;
ans+=(*(++it)-t)*(max3(f[i].v,s[j].v,));
// debug_b(t),debug_b(*it),debug_b(max3(f[i].v,s[j].v,0)),debug_b(i),debug_l(j);
t=*it;
}
cout<<ans<<endl; return ;
}

牛客小白月赛2 I 艺 【归并思想】【离散化】的更多相关文章

  1. 树的最长链-POJ 1985 树的直径(最长链)+牛客小白月赛6-桃花

    求树直径的方法在此转载一下大佬们的分析: 可以随便选择一个点开始进行bfs或者dfs,从而找到离该点最远的那个点(可以证明,离树上任意一点最远的点一定是树的某条直径的两端点之一:树的直径:树上的最长简 ...

  2. 牛客网 牛客小白月赛5 I.区间 (interval)-线段树 or 差分数组?

    牛客小白月赛5 I.区间 (interval) 休闲的时候写的,但是写的心情有点挫,都是完全版线段树,我的一个队友直接就水过去了,为啥我的就超内存呢??? 试了一晚上,找出来了,多初始化了add标记数 ...

  3. 牛客小白月赛8 - E - 诡异数字 数位DP

    牛客小白月赛8 - E - 诡异数字 题意: 求区间中,满足限制条件的数字的个数. 限制条件就是某些数字不能连续出现几次. 思路: 比较裸的数位DP, DP数组开一个dp[len][x][cnt] 表 ...

  4. 牛客小白月赛18 Forsaken给学生分组

    牛客小白月赛18 Forsaken给学生分组 Forsaken给学生分组 链接:https://ac.nowcoder.com/acm/contest/1221/C来源:牛客网 ​ Forsaken有 ...

  5. 牛客小白月赛18 Forsaken喜欢数论

    牛客小白月赛18 Forsaken喜欢数论 题目传送门直接点标题 ​ Forsaken有一个有趣的数论函数.对于任意一个数xxx,f(x)f(x)f(x)会返回xxx的最小质因子.如果这个数没有最小质 ...

  6. 牛客小白月赛19 E 「火」烈火燎原 (思维,树)

    牛客小白月赛19 E 「火」烈火燎原 (思维,树) 链接:https://ac.nowcoder.com/acm/contest/2272/E来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空 ...

  7. 【牛客小白月赛21】NC201604 Audio

    [牛客小白月赛21]NC201604 Audio 题目链接 题目大意: 给出三点 ,求到三点距离相等的点 的坐标. 解析 考点:计算几何基础. 初中蒟蒻表示不会什么法向量.高斯消元..qwq 方法一: ...

  8. 【牛客小白月赛21】NC201605 Bits

    [牛客小白月赛21]NC201605 Bits 题目链接 题目描述 Nancy喜欢做游戏! 汉诺塔是一个神奇的游戏,神奇在哪里呢? 给出3根柱子,最开始时n个盘子按照大小被置于最左的柱子. 如果盘子数 ...

  9. 牛客小白月赛16 小石的妹子 二分 or 线段树

    牛客小白月赛16 这个题目我AC之后看了一下别人的题解,基本上都是线段树,不过二分也可以. 这个题目很自然就肯定要对其中一个进行排序,排完序之后再处理另外一边,另一边记得离散化. 怎么处理呢,你仔细想 ...

随机推荐

  1. 【学习笔记】String进阶:StringBuffer类(线程安全)和StringBuilder类

    一.除了使用String类存储字符串之外,还可以使用StringBuffer类存储字符串.而且它是比String类更高效的存储字符串的一种引用数据类型. 优点: 对字符串进行连接操作时,使用Strin ...

  2. Java - > for, while 及 do.while循环

    为什么要用到循环结构: 按顺序结构执行程序语句(方法或者代码块)只能被执行一次.如果要多次执行,就需要使用到循环结构(循环结构是指在程序中需要反复执行某个功能而设置的一种程序结构) 布尔表达式:是一段 ...

  3. poj 1655 树的重心 && define注意事项

    http://blog.csdn.net/acdreamers/article/details/16905653 题意:给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果 ...

  4. Android应用开发详解

    目录结构 1.Android概述 2.Android开发基础 未完待续……

  5. oracle查询所有用户表的表名、主键名称、索引、外键等

    1.查找表的所有索引(包括索引名,类型,构成列): select t.*,i.index_type from user_ind_columns t,user_indexes i where t.ind ...

  6. Java IntelliJ IDEA 不能显示项目里的文件结构的解决方案

    按下列步骤操作:1. 关闭IDEA2.然后删除项目文件夹下的.idea文件夹3.重新用IDEA工具打开项目

  7. redis的使用方式

    常用的语法以及使用方式:          key中不能包含回车空格等,key不要太长,占用内存.     概念介绍:         差集: a:{1,2,3} b:{2,3,4},以a为锚点,差集 ...

  8. memcached与spring集成

    一.背景 销售CRM(项目A)将负责管理项目信息系统(项目B)的支付与权限 上级要求为避免频繁调用CRM接口,中间放一级缓存,但要做到缓存中保证最新数据 因项目B已使用memcache作缓存,所以决定 ...

  9. Docker 容器中相关软件安装

    Docker 容器中相关软件安装 1.介绍 我们从docker hub下载的centos镜像是只有很少的命令,需要单独安装我们所需的相关软件. 2.安装软件 安装yum-utils软件包 该软件包是辅 ...

  10. WAKE-WIN10-SOFT-CMAKE

    1,CMAKE 官网:https://cmake.org/ 下载:https://cmake.org/download/ BING:https://www.bing.com/search?q=cmak ...