zoukankan      html  css  js  c++  java
  • P1969 积木大赛 题解

    CSDN同步

    原题链接

    简要题意:

    每次把一段区间 (+1),问得到 (a) 数组的最小次数。

    我们可以把 (+1) 得到 (a) 换成,从 (a) 依次 (-1) 得到 (0).

    算法一

    每次求出最小值,然后所有数减掉它。

    这样归并下去。

    时间复杂度: (O(n^2)).

    实际得分:(70pts).

    算法二

    用线段树维护最小值和区间修改。

    时间复杂度:(O(n log n))

    实际得分:(100pts)

    算法三

    你会发现,显然 (a_{i-1}) 会被减去 (a_{i-1}) 次。

    此时如果 (a_{i-1} > a_i) ,则这两个数一共只需要 (a_{i-1}) 次,可以包含。

    否则,就需要 (a_i) 次,也可以理解成 (a_{i-1} + (a_i - a_{i-1}))

    所以,总答案为:

    (sum_{i=1}^n max(a_i-a_{i-1},0))

    其中 (a_0=0).

    这个原理是,能扩展则扩展,否则分立为差。

    时间复杂度:(O(n)).

    实际得分:(100pts).

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=1e5+1;
    typedef long long ll;
    
    inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
    	int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
    
    int n,t;
    ll ans=0;
    
    int main(){
    	n=read(); t=0;
    	for(int i=1,x;i<=n;i++) {
    		x=read(); ans+=max(x-t,0);
    		t=x; // t = a_[i-1] , x = a[i]
    	} printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    最短路
    Codeforces Round #607 (Div. 2) C. Cut and Paste
    第三次训练赛
    训练赛
    day27-反射
    day26-网络编程
    tcp文件上传--多个客户端
    tcp图片上传
    tcp文件上传优化
    tcp文件上传
  • 原文地址:https://www.cnblogs.com/bifanwen/p/12575974.html
Copyright © 2011-2022 走看看