Codeforces Round # 555 (Div. 3) C2. Increasing subsequence (complicated version) (贪心)

题目链接:http://codeforces.com/contest/1157/problem/C2

当左右两边数字相同时,需要判断一下取哪边能得到更长的递增序列

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>
#include <climits>
#include <set>
#include <stack>
#include <string>
#include <map>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
static const int MAX_N = 2e5 + 5;
static const ll Mod = 2009;
char str[MAX_N];
int a[MAX_N];
void solve(){
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    int n;
    while(scanf("%d", &n) != EOF){
        for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
        int s = 0, e = n - 1, cnt = 0, prev = 0;   //prev为序列中最大值
        while(s <= e){
            if(a[s] <= prev){
                while(a[e] > prev && e >= s){
                    prev = a[e--];
                    str[cnt++] = ‘R‘;
                }
                break;
            }
            if(a[e] <= prev){
                while(a[s] > prev && s <= e){
                    prev = a[s++];
                    str[cnt++] = ‘L‘;
                }
                break;
            }
            if(a[s] < a[e] && a[s] > prev){
                prev = a[s++];
                str[cnt++] = ‘L‘;
                continue;
            }
            if(a[s] > a[e] && a[e] > prev){
                prev = a[e--];
                str[cnt++] = ‘R‘;
                continue;
            }
            int e1 = 0, e2 = 0;
            if(a[s] > prev){
                e1 = 1;
                while(s + e1 <= e && a[s + e1] > a[s + e1 - 1]) ++e1;
            }
            if(a[e] > prev){
                e2 = 1;
                while(e - e2 >= s && a[e - e2] > a[e - e2 + 1]) ++e2;
            }
            if(e1 > e2){
                prev = a[s++];
                str[cnt++] = ‘L‘;
            }
            else{
                prev = a[e--];
                str[cnt++] = ‘R‘;
            }
        }
        str[cnt] = ‘\0‘;
        printf("%d\n%s\n", cnt, str);
    }
}
int main() {
    solve();
    return 0;
}

原文地址:https://www.cnblogs.com/xorxor/p/10959984.html

时间: 2024-08-15 23:37:36

Codeforces Round # 555 (Div. 3) C2. Increasing subsequence (complicated version) (贪心)的相关文章

[Codeforces Round #622 (Div. 2)] - C2. Skyscrapers (hard version) (单调栈)

[Codeforces Round #622 (Div. 2)] - C2. Skyscrapers (hard version) (单调栈) C2. Skyscrapers (hard version) time limit per test 3 seconds memory limit per test 512 megabytes input standard input output standard output This is a harder version of the probl

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version) 单调栈

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version) 问题 传送门 我是参考了这篇题解传送门,然后按着思路做出了的(但大佬题解中的sumr[]数组操作我没看懂,然后自己改了改). 摘抄: 维护峰值最优 找左右边的第一个比自己小的元素,维护前缀和,找最大的峰值 l[i]:用单调栈维护左边第一个比它小的数 r[i]:用单调栈维护右边第一个比它小的数 suml[i]:左边的前缀和 sumr[i]:右边的前缀和 然后遍历一遍数组,找到

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)(单调栈,递推)

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version) 题意: 你是一名建筑工程师,现给出 n 幢建筑的预计建设高度,你想建成峰状,如: 1 2 3 2 1 → 1 2 3 2 1 1 2 3 1 2 → 1 2 3 1 1 8 10 6 → 8 10 6 10 6 8 → 10 6 6 问所有建筑的高度和最大为多少. 思路: 单调递增栈栈顶存储以当前点为峰的单侧最低高度下标,另存储以每个点为峰的左右最大高度和. #includ

Codeforces Round #575 (Div. 3) D1. RGB Substring (easy version)

Codeforces Round #575 (Div. 3) D1 - RGB Substring (easy version) The only difference between easy and hard versions is the size of the input. You are given a string s consisting of n characters, each character is 'R', 'G' or 'B'. You are also given a

Codeforces Round #555 (Div. 3) A B C1(很水的题目)

A. Reachable Numbers 题意:设f(x)为 x+1 这个数去掉后缀0的数,现在给出n,问经过无数次这种变换后,最多能得到多少个不同的数. 代码 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<stack> #include<set> #include<

Codeforces Round #555 (Div. 3)[1157]题解

不得不说这场div3是真的出的好,算得上是从我开始打开始最有趣的一场div3.因为自己的号全都蓝了,然后就把不经常打比赛的dreagonm的号借来打这场,然后...比赛结束rank11(帮dreagonm上蓝果然没有食言qwq). (震惊...HA省A队CF青名...) CF1157A Reachable Numbers 水题,分析一下不难发现不超过\(10\)次就会少一位,然后\(10^9\)范围内的数可以到达的数个数显然不多,不妨大力模拟,然后把出现的数扔进set,最后输出set.size(

Codeforces Round #622 (Div. 2)C2 Skyscrapers最大&quot;尖&quot;性矩形,思维

题:https://codeforces.com/contest/1313/problem/C2 题意:给出n个数,分别代表第i个位置所能搭建的最大高度,问以哪一个位置的塔的高度为基准向左的每一个塔都小于等于临近右边的塔,向右每一个塔都大于等于临近的左边的塔所构建的高度之和是最大的,输出最大的高度之和: 分析:我们设一个fir[i]数组,表示当前 i 位置向左能构造的最大高度和(就想阶梯一样,i位置是阶梯的最高处),sec[i]则是向右的: 因为求出这俩个数组后,我们直接o(n)的访问fir[i

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)

题目链接:http://codeforces.com/contest/1313/problem/C2 题意:有n个房子,每个房子可以建的最高层数为a[i],但不可以出现相邻左右两边房子的层数都比中间高的情况,要求总共层数要尽可能的多,输出每个房子应该建几层. 思路:记录左边比自己小的第一个元素,同时可以求出当i为顶端是的前缀和.然后记录右边第一个比自己小的元素,同时可以求出当i为顶端是的后缀和.然后再遍历一篇,看谁为顶端时,总层数最多,最后再依次确定层数即可. #include<stdio.h>

Codeforces Round #555 Div. 3

题目链接:戳我 完了,最菜就是我了.div.3都写不动QAQ A 按照题意模拟即可,注意判重 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<map> #define MAXN 100010 using namespace std; int