CF1144G Two Merged Sequences 题解
1.CSES 1667 Message Route 题解2.P3956 棋盘 题解3.abc233_f Swap and Sort 题解4.abc233_e Σ[k=0..10^100]floor(X/10^k) 题解5.abc233_d Interval 题解6.abc233_c Product 题解7.abc249_f Ignore Operations 题解8.abc249_d Index Trio 题解9.abc248_e K-colinear Line 题解10.abc247_f Cards 题解11.CF1066C Books Queries 题解12.P1038 神经网络 题解13.SeekLuna P1362 拓扑排序 3 题解14.abc232_e Rook Path 题解15.abc235_e MST + 1 题解16.abc234_e Arithmetic Number 题解17.P8786 李白打酒加强版 题解18.abc235_d Multiply and Rotate 题解19.CF1095D Circular Dance 题解20.P6201 & P1985 Fliptile S 题解21.CF1183C Computer Game 题解22.CF1095E Almost Regular Bracket Sequence 题解23.abc256_e Takahashi's Anguish 题解24.abc260_g Scalene Triangle Area 题解25.P8714 填空问题 题解26.abc252_d Distinct Trio 题解27.abc252_f Bread 题解28.abc253_e Distance Sequence 题解29.abc250_e Prefix Equality 题解30.abc250_d 250-like Number 题解31.arc164_a Ternary Decomposition 题解32.abc275_f Erase Subarrays 题解33.abc275_e Sugoroku 4 题解34.abc274_d Robot Arms 2 题解35.abc260_f Find 4-cycle 题解36.abc260_e At Least One 题解37.abc273_e Notebook 题解38.abc271_f XOR on Grid Path 题解39.abc271_e Subsequence Path 题解40.abc271_c Manga 题解41.abc269_f Numbered Checker 题解42.abc270_f Transportation 题解43.CF1077E Thematic Contests 题解44.CF1935D Exam in MAC 题解
45.CF1144G Two Merged Sequences 题解
46.joi2022_yo2_c 国土分割 (Land Division) 题解47.P3588 PUS 题解48.CF1946F Nobody is needed 题解Two Merged Sequences
推销我的洛谷博客。
题意
有一个长度为
若能,输出
输出方案的方法是对于每一位都输出
数据范围
。 。
思路
与
考虑使用动态规划。
- 状态:
表示序列第 位作为递增序列或者递减序列时的最优情况, 代表在递增序列中, 代表在递减序列中。
那么最优化属性呢?很显然,当你把当前位作为当前递增序列的最后一个时,递减序列的最后一个数越大越好,反之,若你把当前位作为当前递减序列的最后一个时,递增序列的最后一个数越小越好。
那么
那么转移就很显然了,这里拿
当上一个数小于当前数时,上一个数作为递增序列的最后一个的状态便可以转移至当前数作为递增序列的最后一个的状态。而如果上一个数作为递减序列时的最小递增序列末项的值小于当前数,便可以让当前数接到上一个数作为递减序列时的递增序列之后,那么此时的递减序列末项值为
总结如下:
取最大值。 取最小值。
其中
- 初始状态:
。 - 合法目标状态:
和 。
那么怎么求出方案呢?很简单,用个数组记录当前状态是如何转移来的,最后逆推即可。
详细见代码。
复杂度
- 时间:
。 - 空间:
。
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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步