Codeforces #550 (Div3) - G.Two Merged Sequences(dp / 贪心)
Problem Codeforces #550 (Div3) - G.Two Merged Sequences
Time Limit: 2000 mSec
Problem Description
Two integer sequences existed initially, one of them was strictly increasing, and another one — strictly decreasing.
Strictly increasing sequence is a sequence of integers [x1<x2<⋯<xk][x1<x2<⋯<xk] . And strictly decreasing sequence is a sequence of integers [y1>y2>⋯>yl][y1>y2>⋯>yl] . Note that the empty sequence and the sequence consisting of one element can be considered as increasing or decreasing.
Elements of increasing sequence were inserted between elements of the decreasing one (and, possibly, before its first element and after its last element) without changing the order. For example, sequences [1,3,4][1,3,4] and [10,4,2][10,4,2] can produce the following resulting sequences: [10,1,3,4,2,4][10,1,3,4,2,4] , [1,3,4,10,4,2][1,3,4,10,4,2] . The following sequence cannot be the result of these insertions: [1,10,4,4,3,2][1,10,4,4,3,2] because the order of elements in the increasing sequence was changed.
Let the obtained sequence be aa . This sequence aa is given in the input. Your task is to find any two suitable initial sequences. One of them should be strictly increasing, and another one — strictly decreasing. Note that the empty sequence and the sequence consisting of one element can be considered as increasing or decreasing.
If there is a contradiction in the input and it is impossible to split the given sequence aa into one increasing sequence and one decreasing sequence, print "NO".
Input
The first line of the input contains one integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of elements in aa.
The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai≤2⋅1050≤ai≤2⋅105), where aiai is the ii-th element of a.
Output
If there is a contradiction in the input and it is impossible to split the given sequence aa into one increasing sequence and one decreasing sequence, print "NO" in the first line.
Otherwise print "YES" in the first line. In the second line, print a sequence of nn integers res1,res2,…,resnres1,res2,…,resn, where resiresi should be either 00 or 11 for each ii from 11 to nn. The ii-th element of this sequence should be 00 if the ii-th element of aa belongs to the increasing sequence, and 11 otherwise. Note that the empty sequence and the sequence consisting of one element can be considered as increasing or decreasing.
Sample Input
5 1 3 6 8 2 9 0 10
Sample Output
YES
1 0 0 0 0 1 0 1 0
题解:两种做法,先说贪心,维护下降序列当前最小值M和上升序列当前最大值m
1、a[i] > M && a[i] < m,自然无解。
2、a[i] < M && a[i] < m,只能加到下降序列。
3、a[i] > M && a[i] > m,只能加到上升序列。
4、a[i] < M && a[i] > m,此时需要考虑a[i+1]与a[i]的大小关系,不妨假设a[i+1] > a[i],那么此时应将a[i]加入上升序列,原因很简单,如果把a[i]加入下降序列,则a[i+1]只能加入上升序列,显然这种方案不如把a[i]与a[i+1]都加入上升序列(下降的没动,上升的变化相同),另一种情况同理。
以上四点给出贪心算法并说明贪心成立。
第二种动态规划,分段决策类的动态规划,无非就是考虑第i个数加到上升还是下降,所以很容易想到二维dp,第一维表处理到第i个数,第二维表加入哪个序列,难想的地方在于要优化什么东西,这里的状态定义就很值得学习了:
dp(i, 0)表示处理完前i个数,将i加入递增序列后递减序列元素中最后一个元素的最大值。
dp(i, 1)表示处理完前i个数,将i加入递减序列后递增序列元素中最后一个元素的最小值。
我们肯定是希望前者越大越好,后者越小越好,这样给后面的数字提供更大的选择空间,其实这样定义状态看似有点绕,其实很合理,因为把i加入递增序列后,递增序列的最小值就有了,所以只需要再维护一下递减的最大值即可,加入递减序列同理。再说状态转移的问题,一般动态规划都是难在状态,此题也不例外,转移不难,就是枚举a[i]和a[i-1]分别放在哪种序列中即可,转移时要记录路径,方便最后输出。
贪心代码没啥说的就不贴了,只给出dp代码。
#include <bits/stdc++.h> using namespace std; #define REP(i, n) for (int i = 1; i <= (n); i++)
#define sqr(x) ((x) * (x)) const int maxn = + ;
const int maxm = + ;
const int maxs = + ; typedef long long LL;
typedef pair<int, int> pii;
typedef pair<double, double> pdd; const LL unit = 1LL;
const int INF = 0x3f3f3f3f;
const LL mod = ;
const double eps = 1e-;
const double inf = 1e15;
const double pi = acos(-1.0); int n;
int a[maxn], dp[maxn][];
int path[maxn][];
int ans[maxn]; int main()
{
ios::sync_with_stdio(false);
cin.tie();
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
cin >> n;
for (int i = ; i <= n; i++)
{
cin >> a[i];
}
dp[][] = INF, dp[][] = -INF;
for (int i = ; i <= n; i++)
{
dp[i][] = -INF, dp[i][] = INF;
if (a[i - ] < a[i] && dp[i][] < dp[i - ][])
{
dp[i][] = dp[i - ][];
path[i][] = ;
}
if (dp[i - ][] > a[i] && dp[i][] > a[i - ])
{
dp[i][] = a[i - ];
path[i][] = ;
}
if (a[i] > dp[i - ][] && dp[i][] < a[i - ])
{
dp[i][] = a[i - ];
path[i][] = ;
}
if (a[i] < a[i - ] && dp[i][] > dp[i - ][])
{
dp[i][] = dp[i - ][];
path[i][] = ;
}
}
if(dp[n][] > -INF)
{
cout << "YES" << endl;
int opt = ;
for(int i = n; i >= ; i--)
{
ans[i] = opt;
opt = path[i][opt];
}
for(int i = ; i <= n; i++)
{
cout << ans[i] << " ";
}
}
else if(dp[n][] < INF)
{
cout << "YES" << endl;
int opt = ;
for(int i = n; i >= ; i--)
{
ans[i] = opt;
opt = path[i][opt];
}
for(int i = ; i <= n; i++)
{
cout << ans[i] << " ";
}
}
else
{
cout << "NO";
}
return ;
}
Codeforces #550 (Div3) - G.Two Merged Sequences(dp / 贪心)的更多相关文章
- Codeforces 1144G Two Merged Sequences dp
Two Merged Sequences 感觉是个垃圾题啊, 为什么过的人这么少.. dp[ i ][ 0 ]表示处理完前 i 个, 第 i 个是递增序列序列里的元素,递减序列的最大值. dp[ i ...
- Codeforces 429C Guess the Tree(状压DP+贪心)
吐槽:这道题真心坑...做了一整天,我太蒻了... 题意 构造一棵 $ n $ 个节点的树,要求满足以下条件: 每个非叶子节点至少包含2个儿子: 以节点 $ i $ 为根的子树中必须包含 $ c_i ...
- Codeforces Round #276 (Div. 1)D.Kindergarten DP贪心
D. Kindergarten In a kindergarten, the children are being divided into groups. The teacher put t ...
- [CodeForces - 1272D] Remove One Element 【线性dp】
[CodeForces - 1272D] Remove One Element [线性dp] 标签:题解 codeforces题解 dp 线性dp 题目描述 Time limit 2000 ms Me ...
- codeforces #579(div3)
codeforces #579(div3) A. Circle of Students 题意: 给定一个n个学生的编号,学生编号1~n,如果他们能够在不改变顺序的情况下按编号(无论是正序还是逆序,但不 ...
- Codeforces 219D. Choosing Capital for Treeland (树dp)
题目链接:http://codeforces.com/contest/219/problem/D 树dp //#pragma comment(linker, "/STACK:10240000 ...
- (第二场)D Money 【dp\贪心】
题目:https://www.nowcoder.com/acm/contest/140/D 题目描述: White Cloud has built n stores numbered from 1 t ...
- 【bzoj4027】[HEOI2015]兔子与樱花 树形dp+贪心
题目描述 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接,我们可以把它 ...
- BZOJ 2021 [Usaco2010 Jan]Cheese Towers:dp + 贪心
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2021 题意: John要建一个奶酪塔,高度最大为m. 他有n种奶酪.第i种高度为h[i]( ...
随机推荐
- #001 Python 00号作业:关于课程
请大家继续思考,你希望我们的课程主要涉略哪些方面?你希望我们的课程能够带给你哪些基本的技能?你希望理论课应该怎么上,实验课应该怎么上?对于我们的课程有什么建议或意见 作为一名计算机专业的学生,对于py ...
- 任务型对话(一)—— NLU(意识识别和槽值填充)
1,概述 任务型对话系统越来越多的被应用到实际的场景中,例如siri,阿里小密这类的产品.通常任务型对话系统都是基于pipline的方式实现的,具体的流程图如下: 整个pipline由五个模块组成:语 ...
- Dubbo 支持哪些序列化协议?
面试题 dubbo 支持哪些通信协议?支持哪些序列化协议?说一下 Hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的? 面试官心理分析 上一个问题,说说 dubbo 的基本工作原理 ...
- 【自然语言处理篇】--以NLTK为基础讲解自然语⾔处理的原理和基础知识
一.前述 Python上著名的⾃然语⾔处理库⾃带语料库,词性分类库⾃带分类,分词,等等功能强⼤的社区⽀持,还有N多的简单版wrapper. 二.文本预处理 1.安装nltk pip install - ...
- .NET Core微服务之基于IdentityServer建立授权与验证服务
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.IdentityServer的预备知识 要学习IdentityServer,事先得了解一下基于Token的验证体系,这是一个庞大的主题 ...
- 如何将Azure DevOps中的代码发布到Azure App Service中
标题:如何将Azure DevOps中的代码发布到Azure App Service中 作者:Lamond Lu 背景 最近做了几个项目一直在用Azure DevOps和Azure App Servi ...
- vue里如何灵活的绑定class以及内联style
在我们平常的前端开发中少不了对DOM的操作,以及样式的动态控制,那我们在使用vue的时候该如何灵活的绑定class呢 1.最简单一个class绑定 v-bind:class设置一个对象,可以动态地切换 ...
- matplotlib安装
Windows / Linux pip 相关依赖 Python (>= 2.7 or >= 3.4) NumPy (>= 1.7.1) setuptools dateutil (&g ...
- JVM平台上的响应式流(Reactive Streams)规范
// Reactive Streams // 响应式流是一个倡议,用来为具有非阻塞后压的异步流处理提供一个标准.大家努力的目标集中在运行时环境(JVM和JavaScript)和网络协议上. 注:响应式 ...
- [Nodejs] 用node写个爬虫
寻找爬取的目标 首先我们需要一个坚定的目标,于是找个一个比较好看一些网站,将一些信息统计一下,比如 url/tag/title/number...等信息 init(1, 2); //设置页数,现在是1 ...