题意:给定一个长度为n的数组a,你至多可以删去其中的一个元素,找出最长的连续(严格)上升子序列的长度。

分析:读完题之后可以发现这道题和模板:连续上升子序列很相像,首先可以确定方向是dp:状态是当前的位置,目标是连续(严格)上升子序列的长度,即dp[i]表示以a[i]为结尾的最长的连续(严格)上升子序列的长度。但是,这道题不同于模板的地方就在于题目中给定了一个条件:至多可以删去其中的一个元素,乍一看似乎很难再做状态转移,但是不妨将删去这件事本身也引入状态转移中来。

不难想到“已经删去一个元素”的状态一定是由“没有删去元素”的状态转移过来的,我们可以使用dp第二维来表示是否已经删去了一个元素,即dp[i][0]表示在没有删去一个元素的前提下以a[i]为结尾的最长(严格)连续上升子序列的最长长度,而dp[i][1]则是以已经山区了一个元素为前提下的最长长度。想到这里,便可以开始推状态转移方程:

首先第一步,先不考虑删去元素的状态转移,dp[i][0]这个状态一定是由dp[i-1][0]转移而来的,即如果a[i] > a[i-1],则dp[i][0] = dp[i-1][0]+1;如果第二维=1,同样也不难想到,在这种情况下也是直接由dp[i-1][1]+1转移而来即可。

当a[i] > a[i-1]时,dp[i][0 or 1] = max(dp[i][0],dp[i-1][0 or 1]+1);

第二步:考虑删去元素的情况。倘若我们现在想要得到dp[i],考虑删去a[i-1],这样删去的时候,在从左到右的递推过程中就可以把所有的情况都覆盖到,而不会漏解或重复运算,并且删去a[i-1]使得dp[i]变化的条件是a[i] > a[i-2],也就是当前这一位数比它之前的之前一位数还要大时,删去它之前的数,可能会导致它的最长长度有所变化,其中就可能导致最大长度变大,因此,当a[i] > a[i-2]时,有:dp[i][1] 由 dp[i-2][0] + 1 转移而来。

当a[i] > a[i-2]时,dp[i][1] = max(dp[i][1],dp[i-2][0]+1);

那么综合前两步,不难得出状态转移方程,递推完方程之后,每一步更新结果即可。

代码:

#include <iostream>
#include <algorithm> using namespace std;
const int N = 200005;
int dp[N][2],a[N];
int main()
{
int n;cin >> n;
for(int i = 1;i <= n;++i)
cin >> a[i];
dp[1][0] = 1;
int res = -1;
for(int i = 2;i <= n;++i)
{
dp[i][0] = 1;dp[i][1] = 1;
if(a[i] > a[i-1])
{
dp[i][0] = max(dp[i-1][0] + 1,dp[i][0]);
dp[i][1] = max(dp[i-1][1] + 1,dp[i][1]);
}
if(a[i] > a[i-2])
dp[i][1] = max(dp[i-2][0] + 1,dp[i][1]);
res = max(res,max(dp[i][0],dp[i][1]));
}
cout << res;
return 0;
}

Codeforces 1272D的更多相关文章

  1. [CodeForces - 1272D] Remove One Element 【线性dp】

    [CodeForces - 1272D] Remove One Element [线性dp] 标签:题解 codeforces题解 dp 线性dp 题目描述 Time limit 2000 ms Me ...

  2. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  3. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  4. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  5. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  6. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  7. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  8. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

  9. CodeForces - 696B Puzzles

    http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...

随机推荐

  1. LR接口测试案例(录制)

  2. 【VS开发】解决位图缩放失真

    当用以下函数加载一张位图时,当窗口发生重绘更改大小时,位图将失真: CBitmap bitmap;  bitmap.LoadBitmap(IDB_BITMAP2);  BITMAP bmp;  bit ...

  3. scrapy 正则汉字的提取方法

    [\u4E00-\u9FA5]

  4. 小程序图片预览 wx.previewImage

      list: [ 'http://img5.imgtn.bdimg.com/it/u=3300305952,1328708913&fm=26&gp=0.jpg', 'http://i ...

  5. Educational Codeforces Round 64 -C(二分)

    题目链接:https://codeforces.com/contest/1156/problem/C 题意:给出n个数和整形数z,定义一对数为差>=z的数,且每个数最多和一个数组成对,求最多有多 ...

  6. PTA(Basic Level)1013.数素数

    令 *P**i* 表示第 i 个素数.现任给两个正整数 M≤N≤104,请输出 *P**M* 到 *P**N* 的所有素数. 输入格式: 输入在一行中给出 M 和 N,其间以空格分隔. 输出格式: 输 ...

  7. linux 内核数据结构之红黑树.

    转载: http://www.cnblogs.com/haippy/archive/2012/09/02/2668099.html https://zh.wikipedia.org/zh/%E7%BA ...

  8. Linux如何查看进程是否启动,查看端口占用

    Linux系统中经常需要查看某个进程是否已经启动,启动位置在哪里,某个端口是否被占用,被哪个进程占用等,这些都可以通过命令来完成,本文讲述如何查看进程是否启动,查看端口占用 1.通过ps -ef | ...

  9. Ajax提交数据后,清空form表单

    按钮不同,页面相同,还需要显示的数据不同,这里会由于页面的缓存问题,导致,每次点开这个页面显示的数据相同. 这不是我们想要的.这就需要清楚表单数据了. 如下: $('#myform')[0].rese ...

  10. Linux Firewalld 简明介绍

    防火墙作为保护服务器不受外部网络流量影响的一种方式.可以让用户定义一系列规则来控制外部网络中流入的流量,从而达到允许或阻塞的效果.firewalld 是防火墙服务的一个守护程序,实现了动态修改拥有 D ...