• 洛谷 P1969 积木大赛


    题目描述

    春春幼儿园举办了一年一度的“积木大赛”。今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi。

    在搭建开始之前,没有任何积木(可以看成n块高度为 0 的积木)。接下来每次操作,小朋友们可以选择一段连续区间[l, r],然后将第第 L 块到第 R 块之间(含第 L 块和第 R 块)所有积木的高度分别增加1。

    小 M 是个聪明的小朋友,她很快想出了建造大厦的最佳策略,使得建造所需的操作次数最少。但她不是一个勤于动手的孩子,所以想请你帮忙实现这个策略,并求出最少的操作次数。

    输入输出格式

    输入格式: 

    输入文件为 block.in

    输入包含两行,第一行包含一个整数n,表示大厦的宽度。

    第二行包含n个整数,第i个整数为hi 。 

    输出格式: 

    输出文件为 block.out

    仅一行,即建造所需的最少操作数。 

    输入输出样例

    5
    2 3 4 1 2
    输出样例#1:
    5

    说明

    【样例解释】

    其中一种可行的最佳方案,依次选择

    [1,5] [1,3] [2,3] [3,3] [5,5]

    【数据范围】

    对于 30%的数据,有1 ≤ n ≤ 10;

    对于 70%的数据,有1 ≤ n ≤ 1000;

    对于 100%的数据,有1 ≤ n ≤ 100000,0 ≤ hi≤ 10000。

    思路:

      这道题很深,你可以做的很麻烦,也可以做的很简单,你都认为那是正解。

      我就想了很多思路,然后用了最麻烦的方法。。但至少练习了一下倍增

      1递归去做  

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    #include<ctime>
    using namespace std;
    const int N=100009;
    int a[N];
    int n;
    int f1[N][20],F;//zhi
    int f2[N][20];//where
    long long ans;
    inline void work(int L,int R,int tot)
    {
        if(L==R)
        {
            ans+=a[L]-tot;
            return ;
        }
        if(L>R)    return ;
        int F=(log2(R-L+1)/log2(2));
        int minn,minw;
        if(f1[L][F]<=f1[R-(1<<F)+1][F])
            minn=f1[L][F],minw=f2[L][F];
        else 
            minn=f1[R-(1<<F)+1][F],minw=f2[R-(1<<F)+1][F];
        ans+=minn-tot;
        work(L,minw-1,minn);work(minw+1,R,minn);
        return ;
    }
    int main()
    {
        
        scanf("%d",&n);
        F=(log2(n)/log2(2));
        for(int i=1;i<=n;i++)    
        {
            scanf("%d",&a[i]);
            f1[i][0]=a[i];
            f2[i][0]=i;
        }
        for(int j=1;j<=F;j++)
        for(int i=1;i<=n;i++)
        {
            if(f1[i][j-1]<=f1[i+(1<<(j-1))][j-1])
                f1[i][j]=f1[i][j-1],f2[i][j]=f2[i][j-1];
            else 
                f1[i][j]=f1[i+(1<<(j-1))][j-1],f2[i][j]=f2[i+(1<<(j-1))][j-1];
        }
        work(1,n,0);
        cout<<ans<<endl;
        return 0;    
    }
    倍增,递归

      2有点贪心吧,我也说不清

      就是如果后一个比前个,大就要加它们的差。

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    #include<ctime>
    using namespace std;
    const int N=100009;
    int x,last,n;
    long long ans;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if(x>last)    ans+=x-last;
            last=x;
        }
        cout<<ans;
        return 0;
    }  
    贪心
  • 相关阅读:
    jenkins使用
    pytest+allure生成接口自动化测试报告
    charles系列
    go语言安装使用
    go语言介绍
    Nginx
    python面试题-python相关
    pyhon全栈开发学习目录
    补充【第二章】supervisor守护进程保障服务
    python全栈开发基础【补充】python中列表排序,字典排序,列表中的字典排序
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7686420.html
Copyright © 2020-2023  润新知