Link: http://codeforces.com/contest/448/problem/C
Question:
Set up n 1 * A [I] boards and change them into a barrier with a width of 1 to a [I]. Now paint the barrier,
The width of the brush is 1, and the brush can be used for any length. You can only brush the brush horizontally or vertically at a time. How many times do you need to brush the brush at least?
Solution:
See here (48492573)
First of all, we can think that if the brush is horizontal, in order to obtain the optimal solution, the current position of the brush must also be horizontal, then the entire yellow fence can be obtained through a vertical brush n times in each case.
Therefore, we adopt a divide-and-conquer strategy for dynamic planning, that is, we divide each State into two cases for discussion,
Horizontal brush: paint the shortest board of the current range [L, R], and then enter its sub-range, that is, the length of the board is higher than that of the current shortest board, then, find out the total cost of all subintervals, that is, the amount of money spent by the brush.
Vertical brush: R-l + 1
Then we can adopt the same rule to divide and conquer, knowing that the wall has only one pillar,
You can directly obtain the optimal solution by means of a vertical brush. Each time you determine the decision, you can adopt a smaller solution of two schemes: horizontal brush and vertical brush.
Code
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 }
Codeforces 448c painting fence (division and Control Law)