Codeforces 448C Painting Fence(分治法)

题目链接:http://codeforces.com/contest/448/problem/C

题目大意:
n个1* a [ i ] 的木板,把他们立起来,变成每个木板宽为1长为 a [ i ] 的栅栏,现在要给栅栏刷漆,
刷子宽1,刷子可以刷任意长,每次只能横着刷或者竖着刷,问最少需要刷几次?
解题思路:
参考了这里(https://blog.csdn.net/qq_24451605/article/details/48492573)
首先我们能够想到,如果横着刷,为了得到最优解,当前刷的位置的下面也必须横着刷,然后对于每种情况都可以通过n次竖着刷得到整个黄色的栅栏。
所以我们采取分治的策略进行动态规划,也就是对于每个状态划分为两种情况讨论,如果要刷横向的话,
横刷:将当前区间[l,r]的最矮的木板刷漆,然后再进入它的子区间即木板长度高于当前最矮木板的区间,然后求出所有子区间总花费就是横着刷的花费。
竖刷:r-l+1
然后我们可以采取同样的策略进行分治,知道墙只有一根柱子的时候,
可以直接通过一次竖着刷得到最优解,每次判断决策时采取先横着刷和直接竖着刷两种方案中较小的方案。

代码

 1 #include<bits/stdc++.h>
 2 #define lc(a) (a<<1)
 3 #define rc(a) (a<<1|1)
 4 #define MID(a,b) ((a+b)>>1)
 5 #define fin(name)  freopen(name,"r",stdin)
 6 #define fout(name) freopen(name,"w",stdout)
 7 #define clr(arr,val) memset(arr,val,sizeof(arr))
 8 #define _for(i,start,end) for(int i=start;i<=end;i++)
 9 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
10 using namespace std;
11 typedef long long LL;
12 const int N=1e5+5;
13 const int INF=0x3f3f3f3f;
14 const double eps=1e-10;
15
16 int a[N];
17
18 LL dfs(int l,int r,int h){
19     if(l==r) return 1;
20     int hh=INF;
21     for(int i=l;i<=r;i++){
22         hh=min(hh,a[i]);
23     }
24     LL sum=hh-h;
25     for(int i=l;i<=r;i++){
26         if(a[i]==hh) continue;
27         int j=i;
28         while(a[j+1]>hh) j++;
29         sum+=dfs(i,j,hh);
30         i=j;
31     }
32     return min((LL)r-l+1,sum);
33 }
34
35 int main(){
36     FAST_IO;
37     int n;
38     cin>>n;
39     for(int i=1;i<=n;i++){
40         cin>>a[i];
41     }
42     cout<<dfs(1,n,0)<<endl;
43     return 0;
44 }

原文地址:https://www.cnblogs.com/fu3638/p/9892300.html

时间: 2024-10-17 14:36:02

Codeforces 448C Painting Fence(分治法)的相关文章

Codeforces 448C Painting Fence:分治

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

codeforces 448C Painting Fence

刷篱笆,只有横和竖, 竖着肯定最多是 n , 另一种 那么每一次先把最下面的那个刷掉,  刷掉之后 ,  继续把上面的  刷掉,, 每一次把  剩下的   再按横着或竖着  刷 就是分治了 #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; #define inf 0x7f7f7f7f int a[6000]; int

codeforce 448C Painting Fence (贪心)

原题地址:http://codeforces.com/problemset/problem/448/C 题意: 略 题解 略 #include<bits/stdc++.h> #define clr(x,y) memset((x),(y),sizeof(x)) using namespace std; typedef long long LL; const int maxn=5000; int A[maxn+5]; int d[maxn+5][20]; void rmq_init(int A[]

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]&

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

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

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

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

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