[CodeForces - 1272D] Remove One Element 【线性dp】
[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】的更多相关文章
- 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 ...
- Codeforces 446A. DZY Loves Sequences (线性DP)
<题目链接> 题目大意: 给定一个长度为$n$的序列,现在最多能够改变其中的一个数字,使其变成任意值.问你这个序列的最长严格上升子段的长度是多少. #include <bits/st ...
- Codeforces 176B (线性DP+字符串)
题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...
- 动态规划——线性dp
我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...
- [线性DP][codeforces-1110D.Jongmah]一道花里胡哨的DP题
题目来源: Codeforces - 1110D 题意:你有n张牌(1,2,3,...,m)你要尽可能多的打出[x,x+1,x+2] 或者[x,x,x]的牌型,问最多能打出多少种牌 思路: 1.三组[ ...
- LightOJ1044 Palindrome Partitioning(区间DP+线性DP)
问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...
- 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门 ...
- POJ 2479-Maximum sum(线性dp)
Maximum sum Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 33918 Accepted: 10504 Des ...
- poj 1050 To the Max(线性dp)
题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...
随机推荐
- 递归的实际业务场景之MySQL 递归查询
喜欢就点个赞呗! 源码<--请点击此处查看 引入 当我看到一些评论时,例如下面的样子.我挺好奇这个功能是怎么样做出来的.进过查阅资料,发现这其实是 MySQL 的递归操作.下面就让我操作一下怎么 ...
- Redis sorted set 常用命令介绍
Redis sorted set 使用: Redis 有序集合(sorted set) Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个 ...
- Java环境变量配置超详细教程
https://blog.csdn.net/Mxdon_on/article/details/89461365 概述 Java的环境配置并不是特别难,但是对刚上手的新手来说确实是一个大问题 首先下载j ...
- DRF源码系列分析
DRF源码系列分析 DRF源码系列分析--版本 DRF源码系列分析--认证 DRF源码系列分析--权限 DRF源码系列分析--节流
- React一键复制
如题,我们怎么在React或者其他的框架中实现一键复制呢,实际上实现一键复制的代码与框架无关,因为他是用的是原生的API,下面我们用React来实现一下 效果: 核心代码: 直接将红框处改为需要 ...
- Linux下如何编辑pdf文件目录
目前,我使用的是系统LinuxMint,之前硬盘没坏时都是用Foxit Reader和Okular查看pdf文件,可是后来发现Foxit Reader十分吃CPU,而且现在换了固态硬盘之后只有120G ...
- 分享一个web安全学习站点
大神建议: https://blog.knownsec.com/Knownsec_RD_Checklist/v3.0.html#FMID_1218170279FM https://websec.rea ...
- 【30天自制操作系统】day05:结构体、文字显示与 GDT/IDT 初始化
输出一个 16 行 8 列的点阵字符 void putfont8(char *vram, int xsize, int x, int y, char c, char *font) { int i; c ...
- MSP430系列单片机特性及应用领域
概述 MSP430系列单片机是德州仪器1996年开始推向市场的一种16位超低功耗的混合信号处理器,给人们留下的最大的亮点是低功耗而且速度快,汇编语言用起来很灵活,寻址方式很多,指令很少,容易上手.主要 ...
- React 组件的生命周期方法
React 组件的生命周期方法 按渲染顺序: 1: componentWillMount() – 在渲染之前执行,在客户端和服务器端都会执行. 2: componentDidMount() – 仅在第 ...