[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问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...
随机推荐
- Java实现数列的排列组合
定义: 排列:从给定个数的元素中取出指定个数的元素,进行排序 组合:从给定个数的元素中仅取出指定个数的元素,不考虑排序 公式: 从n个元素中取出m个元素进行排序的个数: A(m,n)=n(n-1)(n ...
- Dubbo源码分析之SPI(三)
一.概述 本篇介绍自适应扩展,方法getAdaptiveExtension()的实现.ExtensionLoader类本身很多功能也使用到了自适应扩展.包括ExtensionFactory扩展. 通俗 ...
- 【CentOS7】修改yum源
[CentOS7]修改yum源 转载:https://www.cnblogs.com/yangchongxing/p/10645944.html 1.备份源 # mv /etc/yum.repos.d ...
- pipelinedb学习笔记 - 1. Continuous Views (连续视图)
Continuous Views 一.Continuous Views 英文直译过来叫连续视图, 在pipelindb中是被定义为专门用来展示 Stream中数据用的.例如:Stream中有一些用户信 ...
- 稳定易用的 Django 分页库,完善分页功能
作者:HelloGitHub-追梦人物 文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 在 通过 Django Pagination 实现简单分页 中,我们实现了一个简单的 ...
- Git详细教程之创建本地仓库和连接Github仓库
首先要知道不只有代码,任何类型的文件都可以进行版本控制,版本控制很重要的一个特性就是你可以随时修改,比如git会记录你的任何操作,如果你想要回退到任何一个历史操作,你可以通过git轻松达到. 本地仓库 ...
- c++-内联函数和函数重载和默认参数和函数指针
内联函数 C++ 内联函数是通常与类一起使用.如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方. 对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编 ...
- sqoop 安装与使用
Sqoop(发音:skup)是一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库间进行数据的传递,可以将一个关系型数据库(例如 : MySQL ,Oracle ,Postgres等)中的 ...
- windows10远程桌面 删除IP记录
注册表位置: HKEY_CURRENT_USER/ Software/ Microsoft/ Terminal Server client/ servers/ 删除不需要的IP地址即可.
- webpack安装错误 ‘webpack : 无法加载文件’