CF1272D. Remove One Element 题解 动态规划
题目链接:http://codeforces.com/contest/1272/problem/D
题目大意:
给你一个长度为 \(n\) 的数组,你最多删除一个元素(也可以不删),求此条件限制下的最长上升子串长度。
解题思路:
本题涉及算法:动态规划。
首先这里有一个条件“你最多可以删除一个元素”,这个条件会造成我们很多的困扰,所以为了避免困扰,我们先尝试在没有这个条件的情况下解决问题。
在我们没有删除元素的权限下,数组 \(a\) 中的 \(n\) 个元素是固定的,所以此时我们可以定义状态 \(f[i]\) 表示以 \(a[i]\) 结尾并且包含 \(a[i]\) 的最长上升子串的长度,那么我们可以发现(设数组坐标从 \(1\) 开始):
\(f[1]=1\);
当 \(i \gt 1\) 时,
- 如果 \(a[i-1] < a[i]\) ,则 \(f[i] = f[i-1]+1\)
 - 否则,\(f[i]=1\)
 
代码实现:
f[1] = 1;
for (int i = 2; i <= n; i ++) {
    if (a[i-1] < a[i]) f[i] = f[i-1]+1;
    else f[i] = 1;
}
然后我们需要求的最长上升子串长度就是所有 \(f[i]\) 中最大的那个。
稍等一下,我们暂时还是不加上“你最多可以删除一个元素”这个条件。
在加上这个条件之前,我们再定义一个状态 \(g[i]\) 表示以 \(a[i]\) 开头并且包含 \(a[i]\) 的最长上升子串的长度,那么,我们可以得到状态转移方程:
\(g[n] = 1\);
当 \(i < n\) 时,
- 如果 \(a[i] < a[i+1]\),则 \(g[i] = g[i+1]+1\);
 - 否则,\(g[i] = 1\)
 
代码实现(注意 \(g[i]\) 需要从 \(n\) 到 \(1\) 反着推):
g[n] = 1;
for (int i = n-1; i >= 1; i --) {
    if (a[i] < a[i+1]) g[i] = g[i+1]+1;
    else g[i] = 1;
}
那么我们求完 \(f[i]\) 和 \(g[i]\) 之后呢,我们再来加回“你最多可以删除一个元素”这个条件。
首先,如果我们不删除元素,那么答案就是所有 \(f[i]\) 中的最大值,我们开一个变量 \(ans = \max(f[i])\)。
其次,如果我们删除元素的坐标是 \(i\) ,我们假设删除元素后的最长上升子串对应为 \(a[l]\) 到 \(a[r]\),
那么如果 \(i\) 不满足 \(l < i < r\) 的条件,那么我删或者不删 \(a[i]\) 对我答案丝毫不影响(仍然是 \(ans = \max(f[i])\))。
那么什么时候会对答案有影响呢?
就是当 \(1 < i < n\) 且 \(a[i-1] < a[i+1]\) 的时候,我删除 \(a[i]\) 能够使得 \(f[i-1] + g[i+1] > ans\) 的时候,说明删除元素 \(a[i]\) 达到了增长最长上升子串的效果,此时我们更新 \(ans = f[i-1] + g[i+1]\) 。
综上所述,答案应该是
- \(\max(f[i])\) (其中 \((1 \le i \le n)\))
和 - \(\max(f[i-1]+g[i+1])\) (其中 \(1 \lt i \lt n\) 且 \(a[i-1] < a[i+1]\))
 
的较大值。
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200020;
int n, a[maxn], f[maxn], g[maxn], ans;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    f[1] = 1;
    for (int i = 2; i <= n; i ++) {
        if (a[i-1] < a[i]) f[i] = f[i-1]+1;
        else f[i] = 1;
    }
    g[n] = 1;
    for (int i = n-1; i >= 1; i --) {
        if (a[i] < a[i+1]) g[i] = g[i+1]+1;
        else g[i] = 1;
    }
    for (int i = 1; i <= n; i ++) ans = max(ans, f[i]);
    for (int i = 2; i < n; i ++) if (a[i-1] < a[i+1]) ans = max(ans, f[i-1] + g[i+1]);
    cout << ans << endl;
    return 0;
}
												
											CF1272D. Remove One Element 题解 动态规划的更多相关文章
- [CodeForces - 1272D] Remove One Element 【线性dp】
		
[CodeForces - 1272D] Remove One Element [线性dp] 标签:题解 codeforces题解 dp 线性dp 题目描述 Time limit 2000 ms Me ...
 - [LeetCode] Remove Element题解
		
Remove Element: Given an array and a value, remove all instances of that value in place and return t ...
 - 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 ...
 - 洛谷P1002 过河卒 题解 动态规划
		
题目链接:https://www.luogu.com.cn/problem/P1002 题目大意 棋盘上\(A\)点有一个过河卒,需要走到目标\(B\)点.卒行走的规则:可以向下.或者向右.同时在棋盘 ...
 - [LeetCode]Longest Palindromic Substring题解(动态规划)
		
Longest Palindromic Substring: Given a string s, find the longest palindromic substring in s. You ma ...
 - how to remove an element in lxml
		
import lxml.etree as et xml=""" <groceries> <fruit state="rotten"& ...
 - codeforces2B.The least round way 题解 动态规划/模拟
		
题目出处:http://codeforces.com/problemset/problem/2/B 题目描述 给你一个 \(n \times n\) 的二维数组,它包含的元素都是非负整数.你需要寻找一 ...
 - 洛谷P1280 尼克的任务 题解 动态规划/最短路
		
作者:zifeiy 标签:动态规划.最短路 题目链接:https://www.luogu.org/problem/P1280 题目大意: 有k个任务分布在第1至n这n个时间点,第i个任务的于第 \(P ...
 - 洛谷P5664 Emiya 家今天的饭 题解 动态规划
		
首先来看一道题题: 安娜写宋词 题目背景 洛谷P5664 Emiya 家今天的饭[民间数据] 的简化版本. 题目描述 安娜准备去参加宋词大赛,她一共掌握 \(n\) 个 词牌名 ,并且她的宋词总共有 ...
 
随机推荐
- codeforces1249-div3
			
A B C 等比数列的性质,前面的i项的和,不会超过第i+1项 D 有若干个区间,要求每一个点被区间覆盖的次数不能超过k个.问移除的最少的区间的数目. 贪心: 若某个点被覆盖了k次以上,那么肯定是移除 ...
 - Git的提交与查看差异
			
本文转载于:http://blog.csdn.net/crylearner/article/details/7685158 代码提交 代码提交一般有五个步骤: 1.查看目前代码的修改状态 2.查看代码 ...
 - java的System.currentTimeMillis()如何转换成C#的DateTime.Now.Ticks?
			
考虑到我们是东八时区的话,应做如下转换: long milli = System.currentTimeMillis() + 8*3600*1000; long ticks = (milli*1000 ...
 - DOMjudge配置
			
DOMjudge配置补充 系统环境为 Debbian GNU/Linux 9 (stretch) 64-bit 在Web server configuration中, ln -s etc/apache ...
 - MySQL存储引擎MyISAM与InnoDB区别
			
简单的表达. MyISAM 是非事务的存储引擎. innodb是支持事务的存储引擎. innodb的引擎比较适合于插入和更新操作比较多的应用 而MyISAM 则适合用于频繁查询的应用 ...
 - css写一个计算器叭
			
显示效果如图,emoji可替换为数字.
 - Codeforces Round #190 (Div. 1 + Div. 2)
			
A. Ciel and Dancing 模拟. B. Ciel and Flowers 混合类型的数量只能为0.1.2,否则3个可以分成各种类型各自合成. C. Ciel and Robot 考虑一组 ...
 - HDU 5463
			
题意:一个盒子有36个格子.每个格子可以装64个物品,搬运一个箱子是一次搬运,问最少到搬运次数 思路:直接求总需要多少个格子,然后去求盒子,这里求盒子呢有个小技巧,就是用ceil函数 #include ...
 - P1023 活动安排
			
题目描述 某个人可以在n个活动中选择一些出来参加.每个活动都有起止时间.而且每个时间段只能参加一个活动.问,这个人最多能加参加几个活动. 可以在活动结束时,立即开始新的活动. 输入格式 第一行是一个整 ...
 - Java语言中使用OpenMP
			
从去年年中,开始学习Java,主要是维护公司用Java编写的服务器软件.目前,该服务器软件遇到一个问题,在下载大文件时,如果同时下载的用户很多, 服务器软件工作会出现异常,有的用户无法下载.服务器硬件 ...