【CF】Day3

分治+贪心

C. Painting Fence

题目:

思路:

我们贪心的想,每一次是横着涂好还是竖着涂好,如果竖着涂,那么就要涂r-l+1次,但是由于可以横着涂,我们可以考虑先将原数组分割成几个子数组考虑,如果要分割的话,就是要涂min(a1,a2,...an-1,an)次,因为不能跳着涂,所以最多只能涂最小高度这么多

于是我们可以用分治的思想来做了,同时贪心取横涂与竖涂的最小值

代码:

#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define ll long long
#define yes cout << "YES" << endl
#define no cout << "NO" << endl
int n;
int a[5005];

//x代表底下有多少被涂完了
int fuc(int l,int r,int x)
{
    if (l > r) return 0;
    if (l == r) return a[l] > x;
    int mi = l;
    for (int i = l; i <= r; i++)
        if (a[i] < a[mi]) mi = i;
    return min(r - l +1,fuc(l,mi-1,a[mi]) + fuc(mi+1,r,a[mi]) + a[mi] - x);
}

void solve()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    cout << fuc(1, n, 0);
}

int main()
{
//    cin.tie(0)->sync_with_stdio(false);
    int t = 1;
    //cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值