zoukankan      html  css  js  c++  java
  • Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)

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

    题意:有n个房子,每个房子可以建的最高层数为a[i],但不可以出现相邻左右两边房子的层数都比中间高的情况,要求总共层数要尽可能的多,输出每个房子应该建几层。

    思路:记录左边比自己小的第一个元素,同时可以求出当i为顶端是的前缀和。然后记录右边第一个比自己小的元素,同时可以求出当i为顶端是的后缀和。然后再遍历一篇,看谁为顶端时,总层数最多,最后再依次确定层数即可。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<math.h>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<map>
    typedef long long ll;
    using namespace std;
    priority_queue<pair<ll, ll> >que;
    ll a[500005],b[500005],c[500005],sum[500005],sum1[500005];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        for(int i=1;i<=n;i++)
        {
            if(a[i-1]<=a[i])
            {
                b[i]=i-1;
                sum[i]=sum[i-1]+a[i];
            }
            else
            {
                int x=i-1;
                while(1)
                {
                    x=b[x];
                    if(a[x]<=a[i])
                    {
                        sum[i]=sum[x]+(i-x)*a[i];
                        b[i]=x;
                        break;
                    }
                }
            }
        }
        for(int i=n;i>=1;i--)
        {
            if(a[i]>=a[i+1])
            {
                c[i]=i+1;
                sum1[i]=sum1[i+1]+a[i];
            }
            else
            {
                int x=i+1;
                while(1)
                {
                    x=c[x];
                    if(a[x]<=a[i])
                    {
                        sum1[i]=sum1[x]+(x-i)*a[i];
                        c[i]=x;
                        break;
                    }
                }
            }
        }
        ll ma=0,p;
        for(int i=1;i<=n;i++)
        {
            if(sum[i]+sum1[i]-a[i]>ma)
            {
                ma=sum[i]+sum1[i]-a[i];
                p=i;
            }
        }
        ll mi=a[p];
        for(int i=p-1;i>=1;i--)
        {
            mi=min(mi,a[i]);
            a[i]=mi;
        }
        mi=a[p];
        for(int i=p+1;i<=n;i++)
        {
            mi=min(mi,a[i]);
            a[i]=mi;
        }
        for(int i=1;i<n;i++)
            printf("%lld ",a[i]);
        printf("%lld
    ",a[n]);
    }
  • 相关阅读:
    绘制矩形
    绘制线条
    画直线
    画弧线
    绘制贝塞尔曲线
    我关注的一些博客或资源链接
    vim必记指令
    mac下使用vim gcc/g++ 编译cpp(c++)文件并运行
    机器学习算法中如何选取超参数:学习速率、正则项系数、minibatch size
    正则化方法:L1和L2 regularization、数据集扩增、dropout
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/12357500.html
Copyright © 2011-2022 走看看