望你没有因此而|

wnsyou

园龄:2年4个月粉丝:19关注:16

2024-06-15 22:23阅读: 15评论: 0推荐: 0

CF1144G Two Merged Sequences 题解

Two Merged Sequences

推销我的洛谷博客

题意

有一个长度为 n 的序列 a,问能否将其拆成一个严格递增子序列和一个严格递减子序列

若能,输出 YES 并在下一行给出方案,若不能,输出 NO

输出方案的方法是对于每一位都输出 0 或者 1,若输出 0 表示其在递增序列中,否则在递减序列中。

数据范围

  • 1n2×105
  • 0ai2×105

思路

xhrcn 巨佬一起完善出来了思路。

考虑使用动态规划。

  • 状态:dpi,0/1 表示序列第 i 位作为递增序列或者递减序列时的最优情况,0 代表在递增序列中,1 代表在递减序列中。

那么最优化属性呢?很显然,当你把当前位作为当前递增序列的最后一个时,递减序列的最后一个数越大越好,反之,若你把当前位作为当前递减序列的最后一个时,递增序列的最后一个数越小越好

那么 dpi,0 就表示序列第 i 位作为递增序列时的最大递减序列末项的值,dpi,1 就表示序列第 i 位作为递减序列时的最小递增序列末项的值。

那么转移就很显然了,这里拿 dpi,0 举例,dpi,1 也差不多。

当上一个数小于当前数时,上一个数作为递增序列的最后一个的状态便可以转移至当前数作为递增序列的最后一个的状态。而如果上一个数作为递减序列时的最小递增序列末项的值小于当前数,便可以让当前数接到上一个数作为递减序列时的递增序列之后,那么此时的递减序列末项值为 ai1

总结如下:

  • dpi,0={109109i=1dpi1,0ai1<aiai1dpi1,1<ai 取最大值。​
  • dpi,1={109109i=1dpi1,1ai1>aiai1dpi1,0>ai​ 取最小值。​

其中 109109 均为极值,可以自行调整,需保证极大值大于 max1in{ai}2×105,极小值小于 min1in{ai}0​。

  • 初始状态:dp0,0=109,dp0,1=109
  • 合法目标状态:dpn,00dpn,12×105

那么怎么求出方案呢?很简单,用个数组记录当前状态是如何转移来的,最后逆推即可。

详细见代码。

复杂度

  • 时间:O(n)
  • 空间:O(n)

Code

点击查看代码
#include <iostream>
using namespace std;
const int N = 2e5 + 10;
int n, a[N], dp[N][2], lst[N][2]; // lst 用于记录当前状态是如何转移来的,为 0 表示是由 dp[i - 1][0] 转移而来,否则由 dp[i - 1][1] 转移而来
void Output (int x, int y) { // 逆推求方案
if (!x) {
return ;
}
Output(x - 1, lst[x][y]);
cout << y << ' ';
}
int main () {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n, dp[0][0] = 1e9, dp[0][1] = -1e9; // 初始状态
for (int i = 1; i <= n; i++) {
cin >> a[i], dp[i][0] = -1e9, dp[i][1] = 1e9;
// 下面是四种转移方式
if (a[i - 1] < a[i] || i == 1) {
dp[i][0] = dp[i - 1][0], lst[i][0] = 0;
}
if (dp[i - 1][1] < a[i] && a[i - 1] > dp[i][0]) {
dp[i][0] = a[i - 1], lst[i][0] = 1;
}
if (a[i - 1] > a[i] || i == 1) {
dp[i][1] = dp[i - 1][1], lst[i][1] = 1;
}
if (dp[i - 1][0] > a[i] && a[i - 1] < dp[i][1]) {
dp[i][1] = a[i - 1], lst[i][1] = 0;
}
// cout << dp[i][0] << ' ' << dp[i][1] << '\n'; // Debug
}
// 判断目标状态是否合法
if (dp[n][0] != -1e9) {
cout << "YES\n";
Output(n, 0);
} else if (dp[n][1] != 1e9) {
cout << "YES\n";
Output(n, 1);
} else {
cout << "NO";
}
return 0;
}

本文作者:wnsyou の blog

本文链接:https://www.cnblogs.com/wnsyou-blog/p/18249863

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

posted @   wnsyou  阅读(15)  评论(0编辑  收藏  举报
  1. 1 勝利への道 安藤浩和
  2. 2 Minecraft’s End Eric Fullerton
  3. 3 月光曲完整版 贝多芬 云熙音乐
  4. 4 平凡之路 (Live版) 朴树
  5. 5 Minecraft C418
  6. 6 Paradise NiziU
  7. 7 叫我,灰原哀 龙大人不喷火
  8. 8 心机之蛙,一直摸你肚子 ——《名侦探柯南》原创同人曲 炊饭,叶辞樱,温海,寒砧,南柯柯,小茜玛姬,盛姝,阿崔Ac,贝壳初,千湛,兮茶子DaYu,乔慕,黎鹿北,起千温卿,遮阳伞,曲悠
  9. 9 战 歌 此去经年
月光曲完整版 贝多芬 - 云熙音乐
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

暂无歌词

加载中…

{{tag.name}}

{{tran.text}}{{tran.sub}}
无对应文字
有可能是
{{input}}
尚未录入,我来提交对应文字
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示