1. 程式人生 > >2.2最長遞增子序列

2.2最長遞增子序列

題意:在可以改變一個數字的前提之下,算出連續最長遞增的序列的長度

思路:其實就是模擬的找最長的長度就是了,不過不是暴力的每一個都找,在找到一段長度之後,直接跳回這次找到的最後面位置

找幾個例子:1 2 3 6 5這個答案是5,把6修改成4,
而2 3 2 3 4這個答案是4,把3變成1

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include <iomanip>
#include<cmath>
#include<float.h> 
#include<string.h>
#include<algorithm>
#define sf scanf
#define scf(x) scanf("%d",&x)
#define scff(a,b) scanf("%d%d",&a,&b)
#define pf printf
#define prf(x) printf("%d\n",x)
#define mm(x,b) memset((x),(b),sizeof(x))
#include<vector>
#include<queue>
#include<map>
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
typedef long long ll;
const ll mod=1e9+100;
const double eps=1e-8;
using namespace std;
const double pi=acos(-1.0);
const int inf=0xfffffff;
const int N=1e6+2;
int a[N];
int main()
{
    int n,x,last,l=1,low1;//low記錄返回的位置
    int maxn=0;    //答案
    int temp=0;    //記錄有沒有修改
    scf(n);
    rep(i,0,n)
        scf(a[i]);
    last=a[0];    //last是記錄上一個數字是多少
    rep(i,1,n)
    {
        if(a[i]>last)//大於就長度加一,更新last
        {
            last=a[i];
            l++;
        }else
        {
            if(temp==0)        //判斷是否改過一次,如果沒改過就改
            {
                temp++;    //改變標記
                if(i>=2&&(a[i]-a[i-2])>=2)    //這就是第一個例子,可以把當前不符合的,,前一個改小
                last=a[i];
                else                            //這個就是把後一個改大
                last=last+1;
                low1=i;                //low記錄返回的位置
                l++;
            }else
            {
                maxn=max(l,maxn);
                temp=0;
                l=1;
                i=low1;            //返回位置繼續找長度
                last=a[i];
            }
        }
    }
    if(temp==0) l++;    //這個就是第二個例子,最後面的長度,可以把前一個數字改小,長度加一
        maxn=max(maxn,l);
    prf(maxn);
    return 0;
}