题目链接:点我

题意:给定一个序列,询问是否能删除一个数让它成为非递减或者非递增的序列。

   比如说 删除后的序列是1 3 3 5 或者5 3 3 1 或者1 3 5 或者5 3 1 都可以。只要满足删掉某个数,构成非递减或者非递增,就输出YES,如果不能就输出NO

正解(LIS求最长上升子序列):

正着来一遍,反着来一遍 注意要用upper_bound即可:

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int Maxlen(int a[],int n){
  4. int b[];
  5. memset(b,,sizeof(b));
  6. int len = ;
  7. for(int i = ; i < n; i ++)
  8. {
  9. if(len == ||a[i] >= b[len - ])
  10. {
  11. b[len] = a[i];
  12. len ++;
  13. }
  14. else
  15. {
  16. int p = upper_bound(b,b + len,a[i]) - b;
  17. b[p] = a[i];
  18. }
  19. }
  20. return len;
  21. }
  22. int main(){
  23. int t,n;
  24. for(scanf("%d",&t);t--;){
  25. scanf("%d",&n);
  26. int a[],c[];
  27. for(int i = ; i < n ; i++){
  28. scanf("%d",&a[i]);
  29. c[n-i-] = a[i];
  30. }
  31. int len = Maxlen(a,n);
  32. int len1 = Maxlen(c,n);
  33. if(len >= n- || len1 >= n-)puts("YES");
  34. else puts("NO");
  35. }
  36. }

如果想瞎搞也行。。。

因为删除一个嘛,先证明删除一个能不能是非递减的(非递增的把序列倒过来搞一次就行了)

首先,对一个序列前后两个数做差

比如说序列

3 1 4 1 5 做差后(即1-3,4-1,1-4,5-1)是 -2,3,-3,4。发现有2个负数,那就不行。

如果序列是 3 1 1 5。 做差后是-2,0,4。发现有一个负数,是在头部,可以删掉

如果序列是5 6 3 ,7 7,做差后是 1,-3,4,0。发现有一个负数,而且可以跟左右两边的某个数相加变成正数,那么这个3就可以删掉。

如果序列是1 2 3 4,做差后是1,1,1,1 没有负数,本身就可以是非递减。

能看得出来:

做差后的序列:如果有2个及以上负数,那它肯定不可能是非递减。

        如果有一个负数,它在头或者尾,或者在中间而且可以跟左右两边任意一个数相加是正数,即可以是非递减

        如果没有负数,已经是非递减

时间复杂度是O(N),额外需要O(N)的空间存做差后的数组

非递增的话就把数组倒一下再来一次就行了。

代码(很乱):

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cmath>
  4. #include <cstdlib>
  5. #include <ctime>
  6. #include <iostream>
  7. #include <algorithm>
  8. #include <sstream>
  9. #include <string>
  10. #include <vector>
  11. #include <queue>
  12. #include <stack>
  13. #include <map>
  14. #include <set>
  15. #include <utility>
  16. #include <bitset>
  17.  
  18. using namespace std;
  19. #define LL long long
  20. #define pb push_back
  21. #define mk make_pair
  22. #define pill pair<int, int>
  23. #define mst(a, b) memset(a, b, sizeof a)
  24. #define REP(i, x, n) for(int i = x; i <= n; ++i)
  25. int main(){
  26. int t,n;
  27. for(scanf("%d",&t);t--;){
  28. scanf("%d",&n);
  29. int a[],b[],c[];
  30. for(int i = ; i < n ; i++){
  31. scanf("%d",&a[i]);
  32. c[n-i-] = a[i];
  33. }
  34. int f1 = ,ard = -;
  35. int s1 = ,s2 = ;
  36. for(int i = ; i < n ; i++){
  37. b[i] = a[i] - a[i-];
  38. if(b[i] < ){
  39. f1++;
  40. ard = i;
  41. }
  42. if(f1 == ){
  43. break;
  44. }
  45. }
  46. if(f1 == ){
  47. s1 = ;
  48. }
  49. if(f1 == ){
  50. if(ard == || ard == n-){
  51. s1 = ;
  52. }
  53. else if(b[ard] + b[ard-] >= || b[ard] + b[ard+] >= ){
  54. s1 = ;
  55. }
  56. }
  57. f1 = ;
  58. ard = -;
  59. //for(int i = 0 ; i < n ; i++) printf("%d ",c[i]);
  60. for(int i = ; i < n ; i++){
  61. b[i] = c[i] - c[i-];
  62. if(b[i] < ){
  63. f1++;
  64. ard = i;
  65. }
  66. if(f1 == ){
  67. break;
  68. }
  69. }
  70. if(f1 == ){
  71. s2 = ;
  72. }
  73. if(f1 == ){
  74. if(ard == || ard == n-){
  75. s2 = ;
  76. }
  77. else if(b[ard] + b[ard-] >= || b[ard] + b[ard+] >= ){
  78. s2 = ;
  79. }
  80. }
  81. s1||s2?puts("YES"):puts("NO");//s1,s2分别代表在非递减和非递增可不可以满足条件
  82. }
  83. }

HDU5532 Almost Sorted Array(最长上升子序列 or 瞎搞个做差的数组)的更多相关文章

  1. HDU-5532 Almost Sorted Array (LIS)

    题目大意:给一个n个数的序列,问这个序列删掉一个数后是否有序. 题目分析:找最长上升子序列和最长下降子序列,只要有一个的长度不小于n-1即可. 代码如下: # include<iostream& ...

  2. 算法 - 求一个数组的最长递减子序列(C++)

    //************************************************************************************************** ...

  3. Remove Duplicates From Sorted Array

    Remove Duplicates from Sorted Array LeetCode OJ Given a sorted array, remove the duplicates in place ...

  4. [LeetCode]题解(python):033-Search in Rotated Sorted Array

    题目来源 https://leetcode.com/problems/search-in-rotated-sorted-array/ Suppose a sorted array is rotated ...

  5. hunnu 11313 无重复元素序列的最长公共子序列转化成最长递增子序列 求法及证明

    题目:http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11313 湖师大的比赛,见我的另一篇水题题解,这里要说的 ...

  6. ACMDP之最长公共子序列长度—HDU1159

    Common Subsequence Problem Description A subsequence of a given sequence is the given sequence with ...

  7. 最长公共子序列(LCS)问题 Longest Common Subsequence 与最长公告字串 longest common substr

    问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk ...

  8. 最长公共子序列(LCS)、最长递增子序列(LIS)、最长递增公共子序列(LICS)

    最长公共子序列(LCS) [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字 ...

  9. 求解最长递增子序列(LIS) | 动态规划(DP)+ 二分法

    1.题目描述     给定数组arr,返回arr的最长递增子序列. 2.举例     arr={2,1,5,3,6,4,8,9,7},返回的最长递增子序列为{1,3,4,8,9}. 3.解答      ...

随机推荐

  1. 白鹭引擎 - 对象的添加与删除 ( 开关效果 addChild, removeChild )

    class Main extends egret.DisplayObjectContainer { /** * Main 类构造器, 初始化的时候自动执行, ( 子类的构造函数必须调用父类的构造函数 ...

  2. react-native 安卓支持 gif动态图

    需要在android/app/build.gradle文件中添加模块 //这一行没有的话得加上才行 compile "com.facebook.fresco:fresco:1.5.0&quo ...

  3. 关于php MD5加密 与java MD5 加密结果不一致的问题

    针对PHP不是UTF-8编码导致的问题 public String md5(String txt) {              try{                   MessageDiges ...

  4. day21-类的组合

    一.面向对象的组合用法 软件重用的重要方式除了继承之外还有另外一种方式,即:组合组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合 用组合的方式建立了类与组合的类之间的关系,它是一种‘ ...

  5. APP-2.1-Hbuilder与夜神 & HbuilderX与夜神模拟器连接

    经上一步完成Hbuilder.HbuilderX与夜神模拟器的安装,本次介绍下两者之间的连接设置. 1.三者的安装路径 Hbuilder:E:\SAP UI5\HBuilder HbuilderX:D ...

  6. Warning:Configuration 'compile' is obsolete and has been replaced with 'implementation'. It will be

    1.替换 compile为implementation. 2.file->invalidate caches 或者build中的clear

  7. CAS无锁技术

    前言:关于同步,很多人都知道synchronized,Reentrantlock等加锁技术,这种方式也很好理解,是在线程访问的临界区资源上建立一个阻塞机制,需要线程等待 其它线程释放了锁,它才能运行. ...

  8. A New Year, A New Accent!

    A New Year, A New Accent! Share Tweet Share Happy New Year!  Does your list of resolutions include i ...

  9. 如何安装和配置RabbitMQ(转载)

    如何安装和配置RabbitMQ 今天开始一个小小的练习,学习一下安装和配置RabbitMQ,为什么要学它,因为WCF可以完全兼容和使用RabbitMQ了.我们新的大数据系统需要使用消息队列,所以就开始 ...

  10. python模块sys

    #!/bin/env python #-*- encoding=utf8 -*- import sys if __name__=="__main__": # 在解释器启动后, ar ...