HDU5532 Almost Sorted Array (the longest ascending subsequence or messing with a bad array)

Topic link: click me

Question: Given a sequence, ask if it is possible to delete a number to make it a non-decreasing or non-increasing sequence.

   For example, the deleted sequence is 1 3 3 5 or 5 3 3 1 or 1 3 5 or 5 3 1. As long as a certain number is deleted to form a non-decreasing or non-incrementing number, output YES, if not, output NO

Positive solution (LIS finds the longest ascending subsequence):

Do it in the forward direction, and do it in the opposite direction. Pay attention to use upper_bound:

Code:

#include<bits/stdc++.h>
using namespace std;
int Maxlen(int a[],int n){
    int b[100010];
    memset(b,0,sizeof(b));
    int len = 0;
    for(int i = 0; i < n; i ++)  
    {  
        if(len == 0 ||a[i] >= b[len - 1])  
        {  
            b [len] = a [i];  
            len ++ ;  
        }  
        else  
        {  
            int p = upper_bound(b,b + len,a[i]) - b;  
            b[p] = a[i];  
        }  
    }
    return len;
}
int main(){
    int t,n;
    for(scanf("%d",&t);t--;){
        scanf("%d",&n);
        int a[100010],c[100010];
        for(int i = 0 ; i < n ; i++){
            scanf("%d",&a[i]);
            c[n-i-1] = a[i];
        }
        int len = Maxlen(a,n);
        int len1 = Maxlen(c,n);
        if(len >= n-1 || len1 >= n-1)puts("YES");
        else puts("NO");
    }
}

 

It's okay if you want to mess around. . .

Because delete one, first prove that deleting one can be non-decreasing (non-incrementing, just reverse the sequence once)

First, make the difference between the two numbers before and after a sequence

for example sequence

3 1 4 1 5 After doing the difference (ie 1-3,4-1,1-4,5-1) is -2,3,-3,4. If it is found that there are 2 negative numbers, it will not work.

If the sequence is 3 1 1 5. After doing the difference it is -2,0,4. It is found that there is a negative number, which is in the head and can be deleted

If the sequence is 5 6 3 , 7 7, the difference is 1, -3, 4, 0. It is found that there is a negative number, and it can be added to a number on the left and right sides to become a positive number, then the 3 can be deleted.

If the sequence is 1 2 3 4, and the difference is 1,1,1,1 without negative numbers, it can be non-decreasing itself.

It can be seen that:

Sequence after difference: If there are 2 or more negative numbers, it must not be non-decreasing.

        If there is a negative number, it is at the head or tail, or in the middle and can be added to any number on the left and right sides. It is a positive number, that is, it can be non-decreasing

        If there is no negative number, it is already non-decreasing

The time complexity is O(N), and an additional O(N) space is required to store the array after the difference

If it is not incrementing, just reverse the array and do it again.

Code (very messy):

#include <cstdio>  
#include <cstring>  
#include <cmath>  
#include <cstdlib>  
#include <ctime>  
#include <iostream>  
#include <algorithm>  
#include <sstream>  
#include <string>  
#include <vector>  
#include <queue>  
#include <stack>  
#include <map>  
#include <set>  
#include <utility>  
#include <bitset>  

using namespace std;  
#define LL long long  
#define pb push_back  
#define mk make_pair  
#define pill pair<int, int>  
#define mst(a, b)    memset(a, b, sizeof a)  
#define REP(i, x, n)    for(int i = x; i <= n; ++i)
int main(){
    int t,n;
    for(scanf("%d",&t);t--;){
        scanf("%d",&n);
        int a[100010],b[100010],c[100010];
        for(int i = 0 ; i < n ; i++){
            scanf("%d",&a[i]);
            c[n-i-1] = a[i];
        }
        int f1 = 0,ard = -1;
        int s1 = 0,s2 = 0;
        for(int i = 1 ; i < n ; i++){
            b[i] = a[i] - a[i-1];
            if(b[i] < 0){
                 f1 ++ ;
                ard = i;
            }
            if(f1 == 2){
                break;
            }
        }
        if(f1 == 0){
            s1 = 1 ;
        }
        if(f1 == 1){
            if(ard == 1 || ard == n-1){
                s1 = 1 ;
            }
            else if(b[ard] + b[ard-1] >= 0 || b[ard] + b[ard+1] >= 0){
                s1 = 1 ;
            }
        }
        f1 = 0 ;
        ard = -1;
        //for(int i = 0 ; i < n ; i++)    printf("%d ",c[i]);
        for(int i = 1 ; i < n ; i++){
            b[i] = c[i] - c[i-1];
            if(b[i] < 0){
                 f1 ++ ;
                ard = i;
            }
            if(f1 == 2){
                break;
            }
        }
        if(f1 == 0){
            s2 = 1;
        }
        if(f1 == 1){
            if(ard == 1 || ard == n-1){
                s2 = 1;
            }
            else if(b[ard] + b[ard-1] >= 0 || b[ard] + b[ard+1] >= 0){
                s2 = 1;
            }
        }
        s1 ||s2?puts( " YES " ):puts( " NO " );//s1, s2 represent whether the conditions can be satisfied in non-decrement and non-increment respectively
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326014865&siteId=291194637