[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. 深入理解 Java 泛型

  2. JS基础-事件循环机制

    从一道题浅说 JavaScript 的事件循环 原文链接: https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/7 ...

  3. 每天用Mybatis,但是Mybatis的工作原理你真的知道吗?

    近来想写一个mybatis的分页插件,但是在写插件之前肯定要了解一下mybatis具体的工作原理吧,于是边参考别人的博客,边看源码就开干了. 核心部件: SqlSession Executor Sta ...

  4. 14个Java并发容器,你用过几个?

    作者:acupt 前言 不考虑多线程并发的情况下,容器类一般使用ArrayList.HashMap等线程不安全的类,效率更高.在并发场景下,常会用到ConcurrentHashMap.ArrayBlo ...

  5. django----csrf跨站请求伪造 auth组件 settings源码 importlib模块

    目录 importlib模块 csrf跨站请求伪造 form表单发送 ajax发送 csrf装饰器 auth模块 如何创建超级用户(root) 创建用户 校验用户名和密码是否正确 保存用户登录状态 判 ...

  6. linux,centos,php,word转图片方法

    刚开始的时候是客户的活儿,真的是没有想到,被这样一个方法给卡住了,真是醉了,经过漫长的一周,终于搞定了这个问题,以下就来给大家介绍以下这个方法把.能方便大家. (直接转换没办法,所以找了个折中的办法, ...

  7. JS 正则表达式^$详解,脱字符^与美元符$同时写表示什么意思?

     壹 ❀ 引 对于初学正则的同学来说,^$这两个看似简单的字符却在使用中总让匹配结果超出我们的预期,^什么时候表示行首什么时候表示反义?^ $两个一起写表示什么含义?今天我们就来详细聊聊这两个字符. ...

  8. 4.Android-adt安卓打包过程、adb指令学习

    本章学习adt安卓打包过程.adb指令学习.并通过adb将打包的APK发给设备 1.打包 在eclipse中已经帮我们实现打包了. 具体打包流程如下: 最终一个APK包含了如下: classes.de ...

  9. 让终端更好看--Ubuntu OhMyZsh配置指南

    查看shell列表 cat /etc/shells 如果发现没有zsh就安装 安装zsh sudo apt install zsh 设置默认shell chsh -s $(which zsh) 重启主 ...

  10. TCP 连接与 HTTP 请求的相关问题

    1.现代浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开? 默认情况下建立 TCP 连接不会断开,只有在请求报头中声明 Connection: clo ...