[CodeForces - 1272D] Remove One Element 【线性dp】

标签:题解 codeforces题解 dp 线性dp


题目描述

Time limit

2000 ms

Memory limit

262144 kB

Source

Codeforces Round #605 (Div. 3)

Tags

brute force   dp   *1500

Site

https://codeforces.com/problemset/problem/1272/D

题面



Example

Input1

5

1 2 5 3 4

Output1

4

Input2

2

1 2

Output2

2

Input3

7

6 5 4 3 2 4 3

Output3

2

题目大意

给定一个序列\(a[1 \cdots n]\),可以删掉其中的任意一个数(当然也可以选择不删),问这其中最长的连续的严格递增序列的长度是多少?

例如,

给定\(n = 5, \;a[1 \cdots 5] = \text{{1, 2, 5, 3, 4}}\).

如果我们不删除数的话,最长的连续严格递增序列分别为\(\text{{1, 2}}\) 和 \(\text{{3, 4}}\), 长度为2。

如果我们删掉\(a[3] = 5\),最长的连续严格递增序列为\(\text{{1, 2, 3, 4}}\),长度为4。

如果我们删掉其他的数的话,最长的连续严格递增序列长度还是2。

所以最终答案为4,输出4。


解析

天宇给我看这道题的时候就告诉我是一道dp题了,所以一开始就按照dp的思路莽了。

简单的线性dp问题。

  • 首先我们考虑不删除数,找到序列内最长连续严格递增序列的长度如何解决。

    设\(dp[i][0]\)为到第\(i\)个数为止,且包含第\(i\)个数的连续严格递增序列的长度。

    初始化\(dp[1 \cdots n][0] = 1\),因为自己一定是自己所在的严格递增序列的其中的一个元素。

    状态转移方程 $$dp[i][0] = dp[i - 1][0] + 1 ,,(if;; a[i] > a[i - 1])$$

*dp[i][0]的更新情况*

  • 之后我们加入删除一个数的操作。

    想要删除一个数,只有在前两个数比当前这个数小的时候(即 \(a[i] > a[i - 2]\))才有必要。

    设\(dp[i][1]\)为到第\(i\)个数为止,且包含第\(i\)个数的,且在其中任意一个位置删除了一个数或没有删除数的连续严格递增序列长度(也可以理解为到这个位置为止包含它自身的最长连续严格递增序列的长度)。

    初始化\(dp[i][1] = dp[i][0] = 1\)。

    状态转移方程 $$dp[i][1] =

    \begin{cases}

    \max{(dp[i][1], dp[i - 1][1] + 1)}, & if ; a[i] > a[i -1]\[2ex]

    \max{(dp[i][1], dp[i - 2][0] + 1)}, & if; a[i] > a[i - 2]

    \end{cases}$$

    想要删除一个数,需要拿之前没有删除过数的状态\(dp[i - 2][0]\)更新,所以我们也要维护\(dp[1 \cdots n][0]\)序列。

    当\(a[i] > a[i - 2]\)时,可能会出现没必要删除\(a[i - 1]\)的情况\((a[i] > a[i - 1]> a[i - 2])\),所以要比较一下\(dp[i][1]\)与\(dp[i - 2][0] + 1\)的大小。

*dp[i][0]、dp[i][1]* 的更新情况

  • 因为每一个\(dp[i][1]\)是当前\(a[i]\)所在连续严格递增序列的长度,所以想要知道最长的长度,需要最后再扫一遍\(dp[i][1]\)找到最大值。

通过代码

/*
Status
Accepted
Time
46ms
Memory
2364kB
Length
944
Lang
GNU G++11 5.1.0
Submitted
2019-12-18 09:35:42
RemoteRunId
67132818
*/ #include <bits/stdc++.h>
using namespace std; const int MAXN = 2e5 + 50; int a[MAXN], dp[MAXN][2]; inline int read() //快读,2e5的输入量,加入快读能明显加快程序运行速度.
{
int res = 0, f = 1;
char ch; ch = getchar(); while(!isdigit(ch)){
if(ch == '-')
f = -1;
ch = getchar();
}
while(isdigit(ch)){
res = (res << 3) + (res << 1) + ch - 48;
ch = getchar();
} return f * res;
}
int main()
{
int n; n = read(); for(int i = 1; i <= n; i ++){ //读入加dp数组的初始化.
a[i] = read();
dp[i][0] = 1;
dp[i][1] = 1;
} for(int i = 2; i <= n; i ++){ //状态转移.
if(a[i] > a[i - 1]){
dp[i][0] = dp[i - 1][0] + 1;
dp[i][1] = dp[i - 1][1] + 1;
}
if(a[i] > a[i - 2])
dp[i][1] = max(dp[i][1], dp[i - 2][0] + 1);
} int maxx = 0;
for(int i = 1; i <= n; i ++) //找到最大值.
maxx = max(maxx, dp[i][1]);
printf("%d", maxx); return 0;
}

最新文章

  1. MongoDB 初见指南
  2. Sql Server函数全解(三)数据类型转换函数和文本图像函数
  3. supervisor拉起daemon进程(falcon-agent)测试
  4. Android想服务器传图片,透过流的方式。还有读取服务器图片(文件),也通过流的方式。
  5. 2016年中国大学生程序设计竞赛(合肥)-重现赛1008 HDU 5968
  6. Web前端开发基础 第四课(认识CSS样式)
  7. 获得select下拉框的值
  8. Using HiveServer2 - Authentication
  9. foreach---集合已修改;可能无法执行枚举操作。
  10. 如何用JS获取ASP.net中的textbox的值 js获不到text值
  11. ECharts本地部署
  12. 传说中的Markov&quot;不过如此”
  13. Python每日一练(2):找出html中的所有链接(Xpath、正则两个版本)
  14. Oracle的一些命令
  15. Gazebo機器人仿真學習探索筆記(六)工具和实用程序
  16. excle 填充单元格内容到相同长度
  17. hbase-连接流程
  18. mysql 线程等待时间,解决sleep进程过多的办法
  19. 2018-2019 2 20165203 《网络对抗技术》 Exp4 恶意代码分析
  20. python 正则re.search

热门文章

  1. Java多态之动态绑定
  2. 【Web技术】286- 自定义错误及扩展错误
  3. git 中的 merge 和 rebase
  4. js中promise解决callback回调地狱以及使用async+await异步处理的方法
  5. 【NodeJS】nvm
  6. Nginx学习一路向西
  7. python爬虫--爬虫介绍
  8. luogu1337 [JSOI2004]平衡点 / 吊打XXX(模拟退火)
  9. CSS | 圣杯布局、双飞翼布局 | 自适应三栏布局
  10. 图文结合深入理解JS中的this值