https://lydsy.com/JudgeOnline/problem.php?id=1109

分析:

  首先是dp,f[i]表示到第i个的最优值,f[i]=f[j]+1,(j<i,a[j]<a[i],j-a[j]<i-a[i]),三维偏序,可以cdq+线段树转移。实际上由a[j]<a[i]和j-a[j]<i-a[i]可以推出j<i所以二维偏序,直接LIS。

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6 #include<cctype>
 7 #include<set>
 8 #include<queue>
 9 #include<vector>
10 #include<map>
11 using namespace std;
12 typedef long long LL;
13  
14 inline int read() {
15     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
16     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
17 }
18  
19 const int N = 1000005;
20  
21 struct Node{
22     int x, c;
23     bool operator < (const Node &A) const {
24         return x == A.x ? c > A.c : x < A.x;
25     } 
26 }A[N]; 
27 int f[N];
28  
29 int main() {
30     int n = read(), cnt = 0;
31     for (int i = 1; i <= n; ++i) {
32         int x = read();
33         if (i - x >= 0) 
34         A[++cnt].x = x, A[cnt].c = i - x;
35     }
36     if (cnt == 0) {
37         cout << 0; return 0;
38     }
39     int len = 1;
40     sort(A + 1, A + cnt + 1);
41     f[1] = A[1].c;
42     for (int i = 2; i <= cnt; ++i) {
43         if (A[i].x != A[i - 1].x && A[i].c >= f[len]) f[++len] = A[i].c;
44         else {
45             int p = upper_bound(f + 1, f + len + 1, A[i].c) - f;
46             f[p] = A[i].c;
47         }
48     }
49     cout << len;
50     return 0;
51 }
52 
LIS

相关文章:

  • 2021-09-24
  • 2021-07-06
  • 2022-01-10
  • 2022-03-05
  • 2022-12-23
  • 2022-01-04
  • 2021-12-08
  • 2022-12-23
猜你喜欢
  • 2021-12-05
  • 2022-12-23
  • 2022-02-13
  • 2021-08-07
  • 2021-06-02
相关资源
相似解决方案