Title:
To give you an array, ask how many numbers can be changed at most, which can make it become "almost rising". The meaning of "almost rising" is to delete at most one number and then the array will rise strictly.
Explanation:
If not deleted,
If not strictly ascending, we can use n - LIS (LIS means the longest non descending subsequence).
It's a strict rise. Let's first put a[i] - i, and then n - LIS.
The question now is what to do after deleting a number?
Originally, LIS is the minimum value of the end with dp record length of i,
Now add a record to delete a number and the minimum length is i.
Transfer to the code.
Code:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <queue> #include <bitset> #include <map> #include <vector> #include <stack> #include <set> #include <unordered_map> #include <unordered_set> #include <cmath> #ifdef LOCAL #define debug(x) cout<<#x<<" = "<<(x)<<endl; #else #define debug(x) 1; #endif #define chmax(x,y) x=max(x,y) #define chmin(x,y) x=min(x,y) #define lson id<<1,l,mid #define rson id<<1|1,mid+1,r #define lowbit(x) x&-x #define mp make_pair #define pb push_back #define fir first #define sec second using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll, int> pii; const ll MOD = 1e9 + 7; const double eps = 1e-10; const int INF = 0x3f3f3f3f; const ll INFLL = 0x3f3f3f3f3f3f3f3f; const int MAXN = 2e5 + 5; int a[MAXN]; int d[2][MAXN]; int main() { #ifdef LOCAL freopen ("input.txt", "r", stdin); #endif int n; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); a[i] -= i; } memset(d, 0x3f, sizeof(d)); int pre = 0; for (int i = 1; i <= n; i++) { int pos1 = upper_bound(d[0] + 1, d[0] + 1 + i, a[i]) - d[0]; int pos2 = upper_bound(d[1] + 1, d[1] + 1 + i, a[i] + 1) - d[1]; d[1][pre] = min(d[0][pre], d[1][pre]); d[1][pos2] = a[i] + 1; d[0][pre = pos1] = a[i]; } int pos1 = lower_bound(d[0] + 1, d[0] + 1 + n, INF) - d[0] - 1; int pos2 = lower_bound(d[1] + 1, d[1] + 1 + n, INF) - d[1] - 1; printf("%d\n", max(0, min(n - pos1, n - 1 - pos2))); return 0; }