C2. Increasing Subsequence (hard version)(水)
题目链接:https://codeforces.com/contest/1157/problem/C2
题目大意:
给你n个数,每一次你可以选择从最左边拿还是从最右边拿,但是每一次拿都必须必上一次的大,然后要求你找一个最长的上升子序列。
具体思路:
如果左右端点不相等的话,优先选择小的那个,这样我们选择完小的之后,还可以再去拿大的那个。
如果左右端点相等的话,这个时候如果选择了其中一边,只能是这条路走到底了,因为取一个之后,另外的边界没法取了,所以就从这两边选一个最长的上升子序列就好了。
注意点:注意每一次存储上一次选的什么。每一次都需要去比较。
AC代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 # define ll long long
4 const int maxn = 2e5+100;
5 int a[maxn];
6 string str;
7 int n;
8 int judge_L(int pos)
9 {
10 int num=1;
11 for(int i=pos; i<=n; i++)
12 {
13 if(a[i]<a[i+1])
14 {
15 num++;
16 }
17 else
18 break;
19 }
20 return num;
21 }
22 int judge_R(int pos)
23 {
24 int num=1;
25 for(int i=pos; i>=1; i--)
26 {
27 if(a[i]<a[i-1])
28 {
29 num++;
30 }
31 else
32 break;
33 }
34 return num;
35 }
36 int main()
37 {
38 cin>>n;
39 for( int i = 1 ; i <= n ; i++ )
40 {
41 cin>>a[i];
42 }
43 //a[0]=0;
44 // cout<<judge_R(1)<<endl;
45 int l=1,r=n;
46 int pre=0;
47 while(l<=r&&l<=n&&r>=1)
48 {
49 int flag=1;
50 if(a[l]==a[r]&&a[l]>pre)
51 {
52 flag=0;
53 int t1=judge_L(l);
54 int t2=judge_R(r);
55 if(t1>t2)
56 {
57 for(int i=l; i<=l+t1-1; i++)
58 {
59 str+='L';
60 }
61 break;
62 }
63 else
64 {
65 for(int i=r; i>=r-t2+1; i--)
66 {
67 str+='R';
68 }
69 break;
70 }
71 }
72 if(a[l]>pre)
73 {
74 flag=0;
75 if(a[r]<a[l]&&a[r]>pre)
76 {
77 str+='R';
78 pre=a[r];
79 r--;
80 }
81 else
82 {
83 str+='L';
84 pre=a[l];
85 l++;
86 }
87 }
88 else if(a[r]>pre)
89 {
90 flag=0;
91 if(a[l]<a[r]&&a[l]>pre)
92 {
93 str+='L';
94 pre=a[l];
95 l++;
96 }
97 else
98 {
99 str+='R';
100 pre=a[r];
101 r--;
102 }
103 }
104 if(flag)
105 break;
106 }
107 cout<<str.size()<<endl;
108 cout<<str<<endl;
109 }