CF448C Painting Fence (贪心分治)

题面

\(solution:\)

一道蛮水的分治题,但思想很不错(虽然我还是非常天真的以为是积木大赛原题,并且居然还有30分)

看到这个题目,根据贪心的一贯风格,我们肯定能想到将整个栅栏的下面某部分直接用几次横向的操作把它涂掉。然后我们发现如果将涂了色的部分不管,整段栅栏会被我们分成若干个部分(最短的竖条栅栏因为贪心会被横着涂完,然后整个栅栏会被分为左(中)右几个部分)。然后我们将这几个依次用这种办法分治。再然后我们发现我们好像把纵向操作忘记了,它在什么地方用呢?我们在每一次求某段栅栏最小次数时比较一下:将它全部纵向涂色用的步数少还是横纵结合的步数少(这段栅栏被分治时某一部分被全部用了纵向操作)。

然后我们的边界条件就是当某一段栅栏被分得只有一条的时候,直接纵向刷一次即可!

\(code:\)

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>

#define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int

using namespace std;

int n;
int a[5005];

inline int qr(){
    char ch;
    while((ch=getchar())<'0'||ch>'9');
    int res=ch^48;
    while((ch=getchar())>='0'&&ch<='9')
        res=res*10+(ch^48);
    return res;
}

inline int fen(int l,int r,int h){
    if(l>r)return 0;//特判
    if(l==r)return 1;//边界
    int tot=0,mi=inf;
    for(rg i=l;i<=r;++i)
        mi=min(mi,a[i]);//贪心的找能横向涂多少次
    for(rg i=l,j;i<=r;i=j+1){
        for(j=i;j<=r;++j)
            if(a[j]==mi)break;
        tot+=fen(i,j-1,mi);
    }return min(r-l+1,tot+(mi-h));//横纵比较
}

int main(){
    freopen("color.in","r",stdin);
    freopen("color.out","w",stdout);
    n=qr();
    for(rg i=1;i<=n;++i)a[i]=qr();
    printf("%d\n",fen(1,n,0));
    return 0;
}

原文地址:https://www.cnblogs.com/812-xiao-wen/p/10360000.html

时间: 2024-10-16 18:08:44

CF448C Painting Fence (贪心分治)的相关文章

Codeforces Round #256 (Div. 2) C. Painting Fence(分治贪心)

题目链接:http://codeforces.com/problemset/problem/448/C ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593830943

Codeforces 448C Painting Fence:分治

题目链接:http://codeforces.com/problemset/problem/448/C 题意: 有n个木板竖着插成一排栅栏,第i块木板高度为a[i]. 你现在要将栅栏上所有地方刷上油漆. 每次你可以选择竖着刷或横着刷,但必须保证一次刷的地方不能间断. 问你至少要刷几次才能刷满. 题解: 首先有一个贪心结论: 对于当前要刷的一片区域,令minn为这片区域的最小高度. 如果选择横着刷,则至少要将区域底部的minn层刷完. 如图,至少要将下面两层刷完: 然后考虑如何分治: 对于当前的这

CF448C Painting Fence

题意:有n块连着的木板,每个木板的高度为\(h_i\),你需要把这n块木板上色,每次上色你可以选择竖着刷完一块木板,或者横着刷一个高度单位的连续的木板(不能跳跃),问最少需要刷几次? 分析:先只考虑贪心地横着涂:每一次尽可能地涂最长,且在此次横着涂的下方必定都是横着涂的,因为如果下面有竖着涂的,根据最优性,上一次竖着涂的时候肯定要把此次的也涂掉(这个自己想想很容易明白,对于一根木板,绝对不可能下面竖着涂,上面横着涂) 所以对于一串连着的木板\(h_1\),\(h_2\)...\(h_n\),就必

Codeforces Round #256 (Div. 2) C (448C)Painting Fence

分治!首先是一大块,贪行刷和竖刷的最小,再转化为小块............ AC代码如下: #include<iostream> #include<cstring> #include<cstdio> using namespace std; int n; int a[5005]; int solve(int l,int r) { int i,j; int len=r-l+1; int height=a[l]; for(i=l;i<=r;i++) if(a[i]&

codeforces349B - Color the Fence 贪心+DP

题意:1-9每个字母需要消耗ai升油漆,问你用油漆最多刻意画多大的数字 解题思路: 首先我们要贪心,可以知道我最优是先使我们位数尽可能长,然后才是就是位数长的情况下使得从最高位开始尽可能大.所以要取满足最长位最小的那个数,方便我们DP 解题代码: 1 // File Name: 349b.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月24日 星期四 21时40分13秒 4 5 #include<vector> 6 #include&

Codeforces Round #256 (Div. 2)——Painting Fence

题目连接 题意: n个木条,输入n个木条的高度,每个木条的宽度均为1.现在有长宽均为1的刷子,每次可以选择横着刷或者竖着刷,每次刷的时候不能离开木条,问将所有木条均涂色至少需要刷几次.(刷的时候可以经过已经被刷过的地方) n (1?≤?n?≤?5000),1?≤?ai(高度)?≤?109 分析: 分析一下横着和竖着的关系:假设现在已经有一个操作集合S是答案,那么集合中的操作顺序是可以改变的,即横和竖的顺序可以改变(因为可以经过已经涂色的木条),那么不妨先横着涂色.对于当前[l,r]的区间,答案不

递归解Codeforces Round #256 (Div. 2)C. Painting Fence

#include<iostream> #include<map> #include<string> #include<cstring> #include<cstdio> #include<cstdlib> #include<cmath> #include<queue> #include<vector> #include<algorithm> using namespace std; in

Codeforces Round #256 (Div. 2) C. Painting Fence

C. Painting Fence Bizon the Champion isn't just attentive, he also is very hardworking. Bizon the Champion decided to paint his old fence his favorite color, orange. The fence is represented as n vertical planks, put in a row. Adjacent planks have no

codeforces 448C C. Painting Fence(分治+dp)

题目链接: codeforces 448C 题目大意: 给出n个杆子,每个杆子有一个长度,每次可以刷一行或一列,问最少刷多少次可以将整个墙刷成黄色. 题目分析: 首先我们能够想到,如果横着刷,为了得到最优解,当前刷的位置的下面也必须横着刷,然后对于每种情况都可以通过n次竖着刷得到整个黄色的墙. 所以我们采取分治的策略进行动态规划,也就是对于每个状态划分为两种情况讨论,如果要刷横向的话,最矮要刷到最矮的柱子的高度才可能得到比竖着刷优的解,然后就变成了多个具有相同性质的规模更小的墙,然后我们可以采取