CF448C Painting Fence(分治递归/DFS)难度⭐⭐⭐
题目链接
有n块连着的木板,每个木板的高度为hih_ihi,你需要把这n块木板上色,每次 上色你可以选择竖着刷完一块木板,或者横着刷一个高度单位的连续的木板(不能中 间空着的不能跳跃),问最少需要刷几次。(注意相当于有一个宽1的刷子,每次可以刷无限长但是宽度只有1)
5
2 2 1 2 1
3
2
2 2
2
贪心 + 分治 因为每次只能涂一个单位长度的油漆,所以考虑贪心,对于横着涂一次的情况,显然这次涂色肯定是把这一层涂满,并且在这次涂色区域的下方,必定都是横着涂的。但是不一定是横着涂就最优,所以需要比较一下。
所以,对于一串栅栏h1,h2,…,hnh_1,h_2,…,h_nh1,h2,…,hn,如果要横着涂,就必定要从底向上涂min(h1,h2,…,hn)min{(h_1,h_2,…,h_n)}min(h1,h2,…,hn)次。这样以后, h1,h2,…,hnh_1,h_2,…,h_nh1,h2,…,hn就会分成若干不连通的子局面。我们可以直接分治,直接递归爆搜,从前往后遍历,复杂度是 O(n2)O(n^2)O(n2) 的,即先试着横着涂,然后将整个连续的序列分成若干个连通块,对于该连通块继续往下搜,尝试横着涂。最后返回的时候跟直接竖着涂即区间的长度比较取最小值即可。因为 n≤5000n\le 5000n≤5000 可以轻松通过。如果数据再大一点,因为爆搜 O(n2)O(n^2)O(n2) 的瓶颈在于需要 O(n)O(n)O(n) 找最小值,所以我们可以在爆搜的时候开一个线段树维护一下区间的最小值,返回的是最小值的下标即可,可以优化到 O(nlogn)O(nlogn)O(nlogn)。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>using namespace std;
typedef long long ll;
#define int long long
const int N = 2e5 + 7, M = 5e6 + 7, INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-8;
typedef int itn;int n, m, a[N];int dfs(int l, int r, int h)
{if(l < 1 || r < 1) return 0;if(l == r) return min(a[l], 1ll);if(l > r) return 0;int minn = INF, last = l - 1, ans = 0;for(int i = l; i <= r; ++ i) {minn = min(minn, a[i]);}ans = minn - h;//横着涂for(int i = l; i <= r; ++ i) {if(a[i] == minn) {ans += dfs(last + 1, i - 1, minn);last = i;}}ans += dfs(last + 1, r, minn);return min(ans, r - l + 1);//比较横着涂更优还是竖着涂更优
}signed main()
{scanf("%d", &n);for(int i = 1; i <= n; ++i) {scanf("%d", &a[i]);}printf("%lld\n", dfs(1, n, 0));return 0;
}
有任何疑问欢迎评论哦虽然我真的很菜
CF448C Painting Fence(分治递归/DFS)难度⭐⭐⭐相关推荐
- [Leetcode][第889题][JAVA][根据前序和后序遍历构造二叉树][分治][递归]
[问题描述][中等] [解答思路] copyOfRange class Solution {public TreeNode constructFromPrePost(int[] pre, int[] ...
- 顺序表应用7:最大子段和之分治递归法
Description 给定n(1<=n<=50000)个整数(可能为负数)组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的子段和的最 ...
- c 最大子序列和_最大子序列和暴力法、分治+递归法、妙法
你好,我是goldsunC 让我们一起进步吧! 最大子序列和 Question:给定整数(可能有负数),求的最大值(为方便起见,如果所有整数均为负数,则最大子序列和为0). 示例: IN : [-2, ...
- HDU1007 Quoit Design 分治+递归
点击打开链接 Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Oth ...
- [Leetcode][第106题][JAVA][ 从中序与后序遍历序列构造二叉树][分治][递归]
[问题描述][中等] [解答思路] public class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) { ...
- LeetCode 932. 漂亮数组(分治递归/循环)
文章目录 1. 题目 2. 解题 2.1 分治递归 2.2 循环 1. 题目 对于某些固定的 N,如果数组 A 是整数 1, 2, -, N 组成的排列,使得: 对于每个 i < j,都不存在 ...
- 最大子段和之分治递归法
最大子段和之分治递归法 Time Limit: 10 ms Memory Limit: 400 KiB Problem Description 给定n(1<=n<=50000)个整数(可能 ...
- 二叉树非递归dfs——简单思路搞定前中后序遍历
前言:相信很多同学都被二叉树非递归dfs的前中后序遍历方法弄的头疼.网上的答案,什么前中后序遍历各有一套写法,还有什么一个栈的写法,两个栈的写法.看起来能理解,一闭眼自己写都记不住.今天介绍一种用一种 ...
- 函数传参问题,桶排序去重,分治递归,摩尔投票求数组众数,数组中心下标求法
TIPS 1. 我们都知道,地址,指针这两者是完全等价的概念,但是有微小的差别.地址的话是不能够修改的(比如说数组名++就是违法的),而指针的话可以++与--. 2. 以后一旦在代码里面看到字符cha ...
最新文章
- 再谈docker基本命令
- HTML5 progress和meter控件
- 很久没写东西了,留个言。
- Spring MVC 学习笔记 json格式的输入和输出
- 思科网络基础课件_上海思科CCNA培训、思科网络工程师培训
- Mysql8.0可以使用解压版 这个比较快 好像现在都是解压版了
- css 文字重叠_html网页文字重叠 字体叠加显示css如何解决
- 【iOS】利用CocoaPods创建私有库进行组件化开发
- javascript操作表格案例讲解
- keep it SMPL: Automatic estimation of 3d human pose and shape from a single image
- CRM客户关系管理系统
- C#爬虫爬取京东自营笔记本
- 记录:中债|中证|上清所比较容易混淆的金融大机构
- mysql本机ip一般是多少_localhost简介、localhost与 127.0.0.1 及 本机IP 的区别
- 【数学】三角函数小题
- 绝地求生:你知道哪种枪的射速最快吗?它100发子弹只要8秒!
- Excel数据分析之数组
- hdu 5148 Cities dp
- 常见浏览器User-Agent
- Ansible(未完待续)