• CF448C Painting Fence(来自洛谷)(贪心+分治)


    洛谷地址:https://www.luogu.com.cn/problem/CF448C

    题意:

    有n块连着的木板,每个木板的高度为h_ihi,你需要把这n块木板上色,每次 上色你可以选择竖着刷完一块木板,或者横着刷一个高度单位的连续的木板(不能中 间空着的不能跳跃),问最少需要刷几次。

    解析:

    很明显,贪心策略是,优先横着刷每组最小值。

    由于不能跳跃。

    假设最低点位于中间md,那么以它横着刷,这个地方就会变成0,断点不能跳跃,所以区间分为了[L,md-1][md+1,r],自然就是分治的思想了。

    几个细节:

    为什么每次要和r-l+1取最小值呢,因为上述的贪心并不是最优的,因为我们的分治是以横着刷优先,假设有:

    3  3  0  3,分治得到结果是4,但是直接竖着刷,结果是3。

    递归出口:L==R的时候,是不能返回1的,如果此时的a[L]==0,它是不需要刷的,所以要和1取个最小值

    #include<bits/stdc++.h>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int maxn=5e3+20;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    int a[maxn];
    int dfs(int l,int r)
    {
    //    cout<<l<<"--"<<r<<endl;
        if(l>r)
            return 0;  
        if(l==r)
            return min(a[l],1);
        int minn=inf,k;
        for(int i=l;i<=r;i++)
        {
            if(a[i]<minn)
            {
                minn=a[i];
                k=i;
            }
        }
        for(int i=l;i<=r;i++)
        {
            a[i]-=minn;
        }
        int c1=dfs(l,k-1),c2=dfs(k+1,r);
        return min(c2+c1+minn,r-l+1);
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        printf("%d
    ",dfs(1,n));
    }
  • 相关阅读:
    [zz] 从VMM中终止GUEST OS中运行进程
    [zz]Linux流量监控工具 – iftop (最全面的iftop教程)
    [zz]Ubuntu终端下Nethogs网络流量监控工具
    AtomicBoolean运用
    JDK中的URLConnection参数详解
    java读取文本文件数据
    tomcat时区设置
    java的upload
    java复习(set 、list、map)
    NIO学习笔记1
  • 原文地址:https://www.cnblogs.com/liyexin/p/13503948.html
Copyright © 2020-2023  润新知