CF448C Painting Fence

CF448C Painting Fence

洛谷传送门

题意翻译

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


题解:

联想到积木大赛。但是对于这道题来讲还有竖着刷的情况。一般思路肯定是先横着刷,刷不了了再竖着刷。但是这样的正确性难于证明。事实上,也的确是错的。因为如果出现若干小块,这么刷就不如竖着刷更划算。

那么,就按贪心的思路模拟,如果出现分块的情况,就递归下去继续模拟。

所以模拟就是递归。递归就是模拟。

那么代码就显而易见了:

#include<bits/stdc++.h>
using namespace std;
int a[5005],n;
int dfs(int l,int r)
{
	if(l>r) 
        return 0;
	if(l==r)
        return min(1,a[l]); 
	int tot=0,last=l-1,tmp=a[l]; 
	for(int i=l+1;i<=r;i++) 
        tmp=min(tmp,a[i]);
	for(int i=l;i<=r;i++)
	{
		a[i]-=tmp;
		if(!a[i])
		    tot+=dfs(last+1,i-1),last=i; 
	} 
    tot+=dfs(last+1,r); 
	return min(tot+tmp,r-l+1);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) 
        scanf("%d",&a[i]);
	printf("%d
",dfs(1,n));
	return 0;
}
原文地址:https://www.cnblogs.com/fusiwei/p/14016447.html