# 256 div2 C. Painting Fence(分治

该博客介绍了如何使用分治和贪心策略解决一个关于木板涂色的优化问题。给定一排木板,每次可以竖直或水平涂色,目标是最小化涂色次数。通过预处理区间最小值并递归地进行分治,最终得到最少的涂色次数。代码中展示了C++实现的详细过程。
摘要由CSDN通过智能技术生成

C. Painting Fence
题意:
n n n 块连着的木板,每个木板的高度为 h i h_i hi ,你需要把这 n n n 块木板上色,每次上色你可以选择竖着刷完一块木板,或者横着刷一个高度单位的连续的木板,问最少需要刷几次。(注意相当于有一个宽 1 1 1 的刷子,每次可以刷无限长度但是高度只有 1 1 1 或者刷无限高度但宽度只有 1 1 1
思路:
题解
贪心+分治递归
对于区间 [ l , r ] [l,r] [l,r],首先考虑横着刷,也就是需要取 M i n = m i n ( a l , a l + 1 , . . . , a r ) Min = min(a_l,a_{l+1},...,a_r) Min=min(al,al+1,...,ar),先横着刷 M i n Min Min 次,然后因为 M i n Min Min 会把 [ l , r ] [l,r] [l,r] 分割乘若干区间,继续递归求解,典型的分治思想,注意还要比较当前区间横着刷更优还是竖着刷更优
S T ST ST表 预处理一下区间最小值,当然本题 n 2 n^2 n2 也可以过
code:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define eps 1e-6
using namespace std;
const int maxn = 5e3 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
ll a[maxn];
int Log[maxn], st[maxn][25];

int find(int l, int r)
{
	int s = Log[r - l + 1];
	return min(st[l][s], st[r - (1 << s) + 1][s]);
}
int dfs(int l, int r, int h)// h表示h以下已经全部涂完了
{
	if(l < 1 || r < 1 || l > r) return 0;
	if(l == r) return 1ll;
	int Min = find(l, r);// 取当前区间最小值,最小值会把 [l,r] 若干区间,就继续分治 
	int last = l, ans = Min - h;//横着涂
	for(int i = l; i <= r; ++i)	if(a[i] == Min)
		ans += dfs(last, i - 1, Min), last = i + 1;
	ans += dfs(last, r, Min);
	return min(ans, r - l + 1);//比较横着涂更优还是竖着涂更优
}

void work()
{
	for(int i = 2; i <= maxn - 9; ++i) Log[i] = Log[i >> 1] + 1;
	cin >> n;
	for(int i = 1; i <= n; ++i) cin >> a[i], st[i][0] = a[i];
	for(int j = 1; j <= 21; ++j)
		for(int i = 1; i + (1 << j) - 1 <= n; ++i)
			st[i][j] = min(st[i][j-1], st[i+(1<<(j-1))][j-1]);
	cout << dfs(1, n, 0)  << endl;
}

int main()
{
	ios::sync_with_stdio(0);
//	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值