[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;
}

[CodeForces - 1272D] Remove One Element 【线性dp】的更多相关文章

  1. Codeforces Round #605 (Div. 3) D. Remove One Element(DP)

    链接: https://codeforces.com/contest/1272/problem/D 题意: You are given an array a consisting of n integ ...

  2. Codeforces 446A. DZY Loves Sequences (线性DP)

    <题目链接> 题目大意: 给定一个长度为$n$的序列,现在最多能够改变其中的一个数字,使其变成任意值.问你这个序列的最长严格上升子段的长度是多少. #include <bits/st ...

  3. Codeforces 176B (线性DP+字符串)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...

  4. 动态规划——线性dp

    我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...

  5. [线性DP][codeforces-1110D.Jongmah]一道花里胡哨的DP题

    题目来源: Codeforces - 1110D 题意:你有n张牌(1,2,3,...,m)你要尽可能多的打出[x,x+1,x+2] 或者[x,x,x]的牌型,问最多能打出多少种牌 思路: 1.三组[ ...

  6. LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

    问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...

  7. hdu1712 线性dp

    //Accepted 400 KB 109 ms //dp线性 //dp[i][j]=max(dp[i-1][k]+a[i][j-k]) //在前i门课上花j天得到的最大分数,等于max(在前i-1门 ...

  8. POJ 2479-Maximum sum(线性dp)

    Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33918   Accepted: 10504 Des ...

  9. poj 1050 To the Max(线性dp)

    题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...

随机推荐

  1. Appium之环境搭建

    Appium:是开源.跨平台.多语言支持的移动应用自动化工具 测试对象主要有:① 原生app ② 混合app(h5 + web前端基础) ③ 移动web app 测试对象APPy运行平台:  ① io ...

  2. 【JS】小工具

    带天数的倒计时 function countDown(dateline){ var timer=null, //倒计时 current_time=Math.floor(new Date().getTi ...

  3. 基于iCamera App Kit 测试oV5640 500w分辨率 摄像头 总结

    基于iCamera App Kit 测试oV5640 摄像头 总结 iCamera App Kit 下载地址 http://pan.baidu.com/s/1kUMIwB1 可以参考下载链接的说明手册 ...

  4. linux-linux mysql5.7主从搭建

    原理: 1:master,建立二进制日志 , 每产生语句或者磁盘变换,写进日志: 2:slave,建立relaylog日志(中继日志),分析master的binlog. 3:master,建立授权账号 ...

  5. apache与tomcat的区别

    1. Apache是web服务器,Tomcat是应用(java)服务器,它只是一个servlet容器,是Apache的扩展. 2. Apache和Tomcat都可以做为独立的web服务器来运行,但是A ...

  6. GHOST CMS - Package.json

    Package.json The package.json file is a set of meta data about a theme. package.json 文件是一组关于主题的元数据. ...

  7. SpringCloud-使用路由网关统一访问接口(附代码下载)

    场景 SpringCloud-使用熔断器仪表盘监控熔断: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/102673599 Spr ...

  8. FlowPortal:流程节点定义有误,合流节点"合流"没有对应的聚焦节点

    FB版本:6.00c 报错: 流程节点定义有误,合流节点"合流"没有对应的聚焦节点 解决办法:分流和合流之间的节点不能有其他节点汇入.调整如下后,成功保存.

  9. 【编码】彻底弄懂ASCII、Unicode、UTF-8之间的关系

    计算机中的所有字符,说到底都是用二进制的0.1的排列组合来表示的,因此就需要有一个规范,来枚举规定每个字符对应哪个0.1的排列组合,这样的规范就是字符集. ASCII 全称是“美国信息交换标准码”(A ...

  10. Hadoop入门学习笔记总结系列文章导航

    一.为何要学习Hadoop? 这是一个信息爆炸的时代.经过数十年的积累,很多企业都聚集了大量的数据.这些数据也是企业的核心财富之一,怎样从累积的数据里寻找价值,变废为宝炼数成金成为当务之急.但数据增长 ...