【NBUToj】1667 - Hkhv Loves Sequences(模拟,严格递增子串)

  • [1667] Hkhv Loves Sequences

  • 时间限制: 1000 ms 内存限制: 65535 K
  • 问题描述
  • Hkhv has a sequence a, consisting of n integers.

    We‘ll call a sequence ai,ai+1,...,aj (1<= i<= j<= n) a subsegment of the sequence a. The value (j-i+1) denotes the length of the subsegment.

    Your task is to find the longest subsegment of a, such that it is possible to change at most one number (change one number to any integer you want) from the subsegment to make the subsegment strictly increasing.

    You only need to output the length of the subsegment you find.

  • 输入
  • The first line contains integer n (1 <=n <= 10^5). The next line contains n integers a1,a2,...,an (1 <=ai <= 10^9).
  • 输出
  • In a single line print the answer to the problem — the maximum length of the required subsegment.
  • 样例输入
  • 6
    7 2 3 1 5 6
  • 样例输出
  • 5
  • 提示
  • You can choose subsegment a2,a3,a4,a5,a6 and change its 3rd element (that is a4) to 4.
  • 来源
  • Recoder

好开心啊,居然AC了。不过题目表述不太清楚吧?改的数可以改成负数吗?(默认为可以就AC了)

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
	int from,to;
	int l;
}data[100011];
int main()
{
	int u;
	int n;
	int num;
	int a[100011];
	int ans;
	scanf ("%d",&u);
	while (u--)
	{
		scanf ("%d",&n);
		for (int i = 1 ; i <= n ; i++)
			scanf ("%d",&a[i]);
		num = 1;
		ans = 1;
		data[num].from = 1;
		data[num].l = 1;
		for (int i = 2 ; i <= n ; i++)
		{
			if (a[i] > a[i-1])
			{
				data[num].l++;
				data[num].to = i;
				ans = max (ans,data[num].l);
			}
			else
			{
				num++;
				data[num].from = i;
				data[num].to = i;
				data[num].l = 1;
			}
		}
		if (ans == n || ans == n-1)		//特判一下
		{
			printf ("%d\n",n);
			continue;
		}
//		if (ans == n - 1)		//题目不清晰,不知道是否可以把该数改为负数
//		{
//			if ((a[1] < a[2]) || (a[1] >= a[2] && a[2] != 0))
//				printf ("%d\n",n);
//			else
//				printf ("%d\n",ans);
//			continue;
//		}
		ans++;
		for (int i = 1 ; i < num ; i++)
		{
			if (data[i+1].l == 1 || data[i].l == 1)		//子串长度为1挺麻烦的,单独处理下
			{
				ans = max (ans , data[i+1].l + 1);
				ans = max (ans , data[i].l + 1);
				if (data[i+1].l == 1 && i != num-1)
				{
					if (a[data[i+1].to-1] + 1 < a[data[i+2].from])
						ans = max (ans , data[i].l + data[i+2].l + 1);
				}
			}
			else
			{
				if (a[data[i].to-1] + 1 < a[data[i+1].from])		//修改前一个子串的最后一个数
					ans = max (ans , data[i].l + data[i+1].l);
				if (a[data[i+1].from-1] + 1 < a[data[i+1].from+1])		//修改后一个子串的第一个数
					ans = max (ans , data[i].l + data[i+1].l);
			}
		}
		printf ("%d\n",ans);
	}
	return 0;
}
时间: 2024-10-06 23:04:02

【NBUToj】1667 - Hkhv Loves Sequences(模拟,严格递增子串)的相关文章

[2016-04-13][codeforces][447][C][DZY Loves Sequences]

时间:2016-04-13 23:39:47 星期三 题目编号:[2016-04-13][codeforces][447][C][DZY Loves Sequences] 题目大意:给定一串数字,问改变其中一个数字之和,最长能得到多长的严格增加的子串 分析: 维护每个数字往左和往右能延续多长(严格减,增),然后枚举每个点, 如果这个点已经在一个严格增加的序列中,那么ans =min(n, max(ans , l[i] + r[i] + 1)) 即左右两边延伸之后,改变后面非递增的一个数字 注意这

Codeforces Round #FF(255) C. DZY Loves Sequences (LIS升级)

题目:C. DZY Loves Sequences (LIS升级) 题意: 在n个数中,最多改变一个数字,并求能够达到的最长严格上升子序列(连续)长度 分析: 考虑第i个数,能否改变后拼接前后两个字串,并维护当前最大值 状态: left[i]:  表示以i为终点的最长严格上升子序列长度 right[i]: 表示以i为起点的最长严格上升子序列长度 dp[i]:   表示改变第i个数后,拼接前后字串的长度 转移方程:       dp[i] = max{left[i-1] + right[i+1] 

Codeforces Round #FF(255) DIV2 C - DZY Loves Sequences

A - DZY Loves Hash 水题,开辟一个数组即可 #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std; int main(){ int p,n; cin >> p >> n; vector<bool> buckets(302,false); bool flag = fal

DP Codeforces Round #FF (Div. 1) A. DZY Loves Sequences

题目传送门 /* DP:先用l,r数组记录前缀后缀上升长度,最大值会在三种情况中产生: 1. a[i-1] + 1 < a[i+1],可以改a[i],那么值为l[i-1] + r[i+1] + 1 2. l[i-1] + 1 3. r[i+1] + 1 //修改a[i] */ #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int MAXN =

codeforces#FF(div2) DZY Loves Sequences

n个数,可以任意改变其中一个数,求最长的上升子区间长度 思路:记录一个from[i]表示从位置i的数开始最长的上升区间长度 记录一个to[i]表示到位置i的数所能达到的最长上升区间长度 枚举要改变的数的位置i,此时能达到的长度为to[i - 1] + from[i + 1] + 1,取最大值 //#pragma comment(linker, "/STACK:102400000,102400000") //HEAD #include <cstdio> #include &l

[CodeForces - 447C] C - DZY Loves Sequences

C - DZY Loves Sequences DZY has a sequence a, consisting of n integers. We'll call a sequence ai,?ai?+?1,?...,?aj (1?≤?i?≤?j?≤?n) a subsegment of the sequence a. The value (j?-?i?+?1) denotes the length of the subsegment. Your task is to find the lon

codeforces 446A DZY Loves Sequences

codeforces   446A   DZY Loves Sequences         题目链接:http://codeforces.com/problemset/problem/446/A 题目大意:给出一个定长为n的数列a,问改动当中一个数后.可能出现的最长严格上升子段的长度是多少. 题目分析:先不考虑"改动当中一个数"这个条件,这样问题就简单多了,从前到后遍历计数就可以(定义一个数组inc[]长度同a,初始化全部点为1,遍历假设当前点a[i]>a[i-1]就置inc

Codeforces 447C - DZY Loves Sequences

447C - DZY Loves Sequences 思路:dp 代码: #include<bits/stdc++.h> using namespace std; #define ll long long const int INF=0x3f3f3f3f; const int N=1e5+5; int a[N]; int f[N],g[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin>>n; f

Codeforces 447 C DZY Loves Sequences【DP】

题意:给出一列数,在这个序列里面找到一个连续的严格上升的子串,现在可以任意修改序列里面的一个数,问得到的子串最长是多少 看的题解,自己没有想出来 假设修改的是a[i],那么有三种情况, 1.a[i]>a[i-1],那么求出向左能够延伸的最长的长度 2.a[i]<a[i-1],那么求出向右能够延伸的最长的长度 3.如果修改的这个数刚好夹在两个数的中间,这种情况比上面两种都优, 即为a[i-1]<a[i+1]-1,求出左右能够延伸的最长的长度 然后因为a[i]本身还没有算进去,所以求出最大值