SGU 488 Dales and Hills

这给题目和LIS类似,只不过是求连续的单调序列,用单调队列可破之,比如求LDIS(连续单增序列),如果a[i]大于栈顶元素入栈,将top作为序列长度,反过来再扫一遍就是包含该元素的单调递减序列,这样通过LCDS,LCIS函数可得到4个存储某元素左右的单调增,减的数组。然后枚举一遍就可以。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define N 1111111
 5 #define INF 0x0f0f0f0f
 6 using namespace std;
 7 
 8 int stack1[N];//不要在函数里开大数组!!!
 9 int n;
10 void LCIS(int dp[],int a[])
11 {
12     int top=0;
13     stack1[top]=-INF;
14     for(int i=1;i<=n;i++)
15     {
16         if(a[i]>stack1[top])
17         {
18             stack1[++top]=a[i];
19             dp[i]=top;
20         }
21         else top=1,stack1[1]=a[i],dp[i]=top;
22     }
23 }
24 void LDIS(int dp[],int a[])
25 {
26     int top=0;
27     stack1[top]=INF;
28     for(int i=1;i<=n;i++)
29         if(a[i]<stack1[top])
30     {
31         stack1[++top]=a[i];
32         dp[i]=top;
33     }
34     else top=1,stack1[top]=a[i],dp[i]=top;
35 }
36 
37 int dp1[N],dp2[N],dp3[N],dp4[N];
38 int a[N],b[N];
39 
40 int main(void)
41 {
42     int tc;
43     scanf("%d",&tc);
44     while(tc--)
45     {
46         scanf("%d",&n);
47         for(int i=1;i<=n;i++)
48             scanf("%d",a+i),b[n+1-i]=a[i];
49         LCIS(dp1,a);
50         LCIS(dp2,b);
51         LDIS(dp3,a);
52         LDIS(dp4,b);
53         int ans1=0,ans2=0;
54         for(int i=1;i<=n;i++)
55            {
56             ans1=max(ans1,min(dp1[i]-1,dp2[n+1-i]-1));
57             ans2=max(ans2,min(dp3[i]-1,dp4[n+1-i]-1));
58            }
59         printf("%d %d\n",ans1,ans2);
60     }
61     return 0;
62 }

 

你可能感兴趣的:(ls)