题目链接: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 }