返回顶部

Codeforces Round #555 (Div. 3) C2. Increasing Subsequence (hard version) (贪心)

  • 题意:给你一组数,每次可以选队首或队尾的数放入栈中,栈中元素必须保持严格单增,问栈中最多能有多少元素,并输出选择情况.

  • 题解:首先考虑队首和队尾元素不相等的情况,如果两个数都大于栈顶元素,那么我们选小的放进去,否则选择比栈顶元素大的放进去,该题重点在于队首和队尾元素相同的情况,由于他们相同,那么我们如果将某一个数放进去后,因为栈中是严格单调的,那么假如我们选左边,那么右边就永远不可能再选了,同理选右边也是一样,所以我们在两边分别跑一下,求一个最长上升数组长度即可.

  • 代码:

    int n;
    int a[N];
    int stk[N];
    int cnt;
    vector<char> v;
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        cin>>n;
        rep(i,1,n) cin>>a[i];
    
        int i=1,j=n;
    
        while(i<=j){
        	if(a[i]>stk[cnt] && a[j]>stk[cnt]){
        		if(a[i]<a[j]){
        			stk[++cnt]=a[i];
        			v.pb('L');
        			i++;
        		}
        		else if(a[i]>a[j]){
        			stk[++cnt]=a[j];
        			v.pb('R');
        			j--;
        		}
        		else{
        			int pos1=i;
        			int pos2=j;
        			while(a[pos1]<a[pos1+1] && pos1<j){
        				pos1++;
        			}
        			while(a[pos2]<a[pos2-1] && pos2>i){
        				pos2--;
        			}
        			if(pos1-i>j-pos2){
        				rep(k,1,pos1-i+1) v.pb('L');
        			}
        			else{
        				rep(k,1,j-pos2+1) v.pb('R');
        			}
        			break;
        		}
        	}
        	else if(a[i]>stk[cnt] && a[j]<=stk[cnt]){
        		stk[++cnt]=a[i];
        		v.pb('L');
        		i++;
        	}
        	else if(a[i]<=stk[cnt] && a[j]>stk[cnt]){
        		stk[++cnt]=a[j];
        		v.pb('R');
        		j--;
        	}
        	else if(a[i]<=stk[cnt] && a[j]<=stk[cnt]) break;
        }
    
        cout<<(int)v.size()<<'\n';
    
        for(char w : v) cout<<w;
    
        return 0;
    }
    
posted @ 2020-11-18 11:25  Rayotaku  阅读(76)  评论(0编辑  收藏  举报