• NOIp2018D1T1 积木大赛 【思维】


    题目传送门

    感觉不是很难,但是需要一些思考...

    可以发现,贪心地向尽量大的区间添加,但是存在一些比较小的数,它们不需要再加了,就会从那个地方断成两个区间。所以刚开始想到的做法就是统计每一种数的数量,每一次加过之后就能知道现在的一排积木被分成了多少段,每一段都要单独来加一次。

    但是,存在整个区间都不需要再加的情况,这个时候这种方法还是会把这个区间再加一次。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<cstring>
     5 #include<queue>
     6 #include<map>
     7 #include<iostream>
     8 #include<stack>
     9 using namespace std;
    10 #define ll long long
    11 #define INF 0x3f3f3f3f
    12 #define N 10005
    13 int rd()
    14 {
    15     int f=1,s=0;char c=getchar();
    16     while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    17     while(c>='0'&&c<='9'){s=(s<<3)+(s<<1)+(c^48);c=getchar();}
    18     return f*s;
    19 }
    20 int n,cnt[N];
    21 ll ans=0;
    22 int main() 
    23 {
    24     int n=rd(),maxx=0;
    25     for(int i=1;i<=n;i++)
    26     {
    27         int tmp=rd();
    28         maxx=max(maxx,tmp);
    29         if(i!=1&&i!=n) cnt[tmp]++;
    30     }
    31     int seg=1;
    32     for(int i=1;i<=maxx;i++)
    33     {
    34         ans+=seg;
    35         seg=seg-1+cnt[i]+1;
    36     }
    37     printf("%lld
    ",ans);
    38     return 0;
    39 }
    Code

    我们发现,一个区间最终需要加的次数等于这个区间中的最大值。把整个数列从递减的地方断开,分成若干个区间。区间中的最大值决定了区间被加的次数,而这个区间中的最小值也很重要,如果前面有数大于最小值的话,这个区间被加的次数的前 最小值 次都可以和上一个区间合并,可以省去 最小值 次。

    就做完啦。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<cstring>
     5 #include<queue>
     6 #include<map>
     7 #include<iostream>
     8 #include<stack>
     9 using namespace std;
    10 #define ll long long
    11 #define INF 0x3f3f3f3f
    12 #define N 10005
    13 int rd()
    14 {
    15     int f=1,s=0;char c=getchar();
    16     while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    17     while(c>='0'&&c<='9'){s=(s<<3)+(s<<1)+(c^48);c=getchar();}
    18     return f*s;
    19 }
    20 int n;
    21 ll ans=0;
    22 int last=0;
    23 int main() 
    24 {
    25     int n=rd();
    26     for(int i=1;i<=n;i++)
    27     {
    28         int tmp=rd();
    29         if(tmp<last) ans+=last,ans-=tmp,last=tmp;
    30         else last=tmp;
    31     }
    32     ans+=last; 
    33     printf("%lld
    ",ans);
    34     return 0;
    35 }
    Code
  • 相关阅读:
    Redis之七种武器
    Redis与Memcached的区别
    java优化占用内存的方法(一)
    Java内存区域与内存溢出异常(二)
    深入理解java垃圾回收机制
    从JAVA多线程理解到集群分布式和网络设计的浅析
    大型网站系统架构系列:分布式消息队列(一)
    大型网站系统架构系列:分布式消息队列(二)
    大型分布式网站架构技术总结
    40个Java多线程问题总结
  • 原文地址:https://www.cnblogs.com/lyttt/p/11845382.html
Copyright © 2020-2023  润新知