Hills——一道转移方程很“有趣”的线性DP
题目描述
Welcome to Innopolis city. Throughout the whole year, Innopolis citizens suffer from everlasting city construction.
From the window in your room, you see the sequence of n hills, where i-th of them has height ai. The Innopolis administration wants to build some houses on the hills. However, for the sake of city appearance, a house can be only built on the hill, which is strictly higher than neighbouring hills (if they are present). For example, if the sequence of heights is 5, 4, 6, 2, then houses could be built on hills with heights 5 and 6 only.
The Innopolis administration has an excavator, that can decrease the height of an arbitrary hill by one in one hour. The excavator can only work on one hill at a time. It is allowed to decrease hills up to zero height, or even to negative values. Increasing height of any hill is impossible. The city administration wants to build k houses, so there must be at least k hills that satisfy the condition above. What is the minimum time required to adjust the hills to achieve the administration's plan?
However, the exact value of k is not yet determined, so could you please calculate answers for all k in range ? Here denotes n divided by two, rounded up.
Input
The first line of input contains the only integer n (1 ≤ n ≤ 5000)—the number of the hills in the sequence.
Second line contains n integers ai (1 ≤ ai ≤ 100 000)—the heights of the hills in the sequence.
Output
Print exactly numbers separated by spaces. The i-th printed number should be equal to the minimum number of hours required to level hills so it becomes possible to build i houses.
Examples
5
1 1 1 1 1
1 2 2
3
1 2 3
0 2
5
1 2 3 2 2
0 1 3
Note
In the first example, to get at least one hill suitable for construction, one can decrease the second hill by one in one hour, then the sequence of heights becomes 1, 0, 1, 1, 1 and the first hill becomes suitable for construction.
In the first example, to get at least two or at least three suitable hills, one can decrease the second and the fourth hills, then the sequence of heights becomes 1, 0, 1, 0, 1, and hills 1, 3, 5 become suitable for construction.
题目大意:
有n座山,在山上建房子,需要保证有房子的山的高度比它两边的山的高度都要高,否则,就把比它高的山挖到比它低。每分钟可以令一座山的高度减一,分别求建1~n/2幢房子花费的最短时间
思路分析:
又是一个线性DP,一步一步往后推就行了
题目不是很难理解,但是最后让求的这个东西就比较有意思了,1~n/2,为什么是n/2而不是n?——显然,两座相邻的山没法同时建房子,要不你就挖去吧,地心挖穿也建不成(开个玩笑)。注意:这里得到一个很关键的性质——所建的房子必须相间,相间,相间!!!
常规思路,从1到n,当做终点进行处理,那我们就只需考虑这个终点前面的山的高度,但是这道题不一样在哪里了呢?——每个点有两点状态,即建房子或不建房子,那么怎么处理呢?数组多开一维不就得了,b( ̄▽ ̄)d
每个点的两种状态各需要一个转移方程,一个建房子的,一个不建房子的。
(1)第i座山建房子的:(划重点)第i座山如果建房子的话,那么第i-1座山肯定不能建,经过这座山时也不会增加时间,那我们就直接蹦到i-2去考虑。i-2同样也有两种情况,建或不建——如果不建,那就拿第i座和第i-1座比较,看看要不要挖;如果建了,那就拿i-2和n共同与i-1进行比较,因为i-1要满足比它们两个都要低。
(2)第i座山不建房子的:那这个时候i-1就可以考虑建房子了,这个情况就比较简单了
细节见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = +;
int h[];
int dp[][][];
int main(){
memset(dp,0x3f,sizeof(dp));
dp[][][]= dp[][][] = dp[][][] =; //初始化,这里其实省了一个循环,把dp[i][0][0]放到下面的dp循环里了
h[]=0x3f3f3f3f; //设为无限大,是为了不干扰后面的操作,而且h[0]一定会出现
int n;scanf("%d",&n);
for(int i=;i<=n;++i){
scanf("%d",&h[i]);
}
for(int i=;i<=n;++i){
dp[i][][]=dp[i-][][]; //前面省的初始化化放到这里了
for(int j=;j<=(i+)/;++j){ //这个括号可能有点长,但其实并不太复杂
dp[i][j][]=min(dp[i-][j-][]+max(,h[i-]-h[i]+), //max函数,其实是代替了if,如果h[i-1]-h[i]+1小于0,说明i-1更矮,就不用挖掉了
dp[i-][j-][]+max(,h[i-]-min(h[i],h[i-])+)); //h[i]和h[i-2],哪个高出来得更多,就挖哪个,这样另一个就也比i-1矮了
dp[i][j][]=min(dp[i-][j][],
dp[i-][j][]+max(,h[i]-h[i-]+)); //上面那个理解了这个就没问题了
}
}
for(int i=;i<=(n+)/;++i){
printf("%d ", min(dp[n][i][],dp[n][i][]));
}
return ;
}
写了这么多,你会明白的对吧(*╹▽╹*)
Hills——一道转移方程很“有趣”的线性DP的更多相关文章
- 『最大M子段和 线性DP』
最大M子段和(51nod 1052) Description N个整数组成的序列a[1],a[2],a[3],-,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M &g ...
- 最长子序列(线性DP)学习笔记
子序列和子串不一样.子串要求必须连续,而子序列不需要连续. 比如说\(\{a_1,a_2\dots a_n\}\),他的子串就是\(\{a_i,a_{i+1},\dots, a_j|1\leq i\l ...
- 线性DP之机器分配
题目大意 自己瞅 (懒得打了) 思路 前面是很简单的线性dp,后面是模拟递归输出方案, 模拟递归可以设ny为机器数机器数,nx表示第nx个公司,tot为总盈利,那么则有\(a[nx][i]+dp[nx ...
- [线性DP][codeforces-1110D.Jongmah]一道花里胡哨的DP题
题目来源: Codeforces - 1110D 题意:你有n张牌(1,2,3,...,m)你要尽可能多的打出[x,x+1,x+2] 或者[x,x,x]的牌型,问最多能打出多少种牌 思路: 1.三组[ ...
- 线性dp
线性dp应该是dp中比较简单的一类,不过也有难的.(矩乘优化递推请出门右转) 线性dp一般是用前面的状态去推后面的,也有用后面往前面推的,这时候把循环顺序倒一倒就行了.如果有的题又要从前往后推又要从后 ...
- 动态规划——线性dp
我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...
- 线性DP详解
顾名思义,线性DP就是在一条线上进行DP,这里举一些典型的例子. LIS问题(最长上升子序列问题) 题目 给定一个长度为N的序列A,求最长的数值单调递增的子序列的长度. 上升子序列B可表示为B={Ak ...
- 【洛谷P1854】花店橱窗 线性dp+路径输出
题目大意:给定 N 个数字,编号分别从 1 - N,M 个位置,N 个数字按照相对大小顺序放在 M 个位置里,每个数放在每个位置上有一个对答案的贡献值,求一种摆放方式使得贡献值最大. 题解:一道典型的 ...
- 动态规划_线性dp
https://www.cnblogs.com/31415926535x/p/10415694.html 线性dp是很基础的一种动态规划,,经典题和他的变种有很多,比如两个串的LCS,LIS,最大子序 ...
随机推荐
- SQL Server账号密码(sa)登录失败 错误原因:233
(其实以前经常用的时候,都很简单,最近一段时间不用了,再一看发现都忘记的差不多了,还是写一篇博客吧,防止下一次再在这种问题上面浪费时间) 右键此电脑,点击管理 如果没有此电脑打开文件夹 在这里右键也是 ...
- java代码(5) ---guava之Multiset
guava之Multiset 一.概述 Guava提供了一个新集合类型Multiset,它可以多次添加相等的元素,且和元素顺序无关,Multiset继承于JDK的Collection接口,而不是Se ...
- 汇编指令:push、pop
8086CPU出栈入栈都是以字为单位进行的. push ax 由一下两步完成 1.SP=SP-2 2.将ax中的内容送入SS:SP指向的内存单元 pop ax 1.将SS:SP指向的内存单元中的内容送 ...
- 深入剖析AQS
目录 摘要 AbstractQueuedSynchronizer实现一把锁 ReentrantLock ReentrantLock的特点 Synchronized的基础用法 ReentrantLock ...
- yum安装配置MySQL数据库
1.配置yum源 # 先安装wget yum install wget -y 2.下载mysql源安装包 wget http://dev.mysql.com/get/mysql57-commu ...
- CMDB 和自动化运维
目录 传统运维和自动化运维的对比 CMDB CMDB 的几种实现方式 传统运维和自动化运维的对比 1.企业中,项目的发布流程 产品经理调研需求 -->三方开会讨论(开发,产品,运维,测试) -– ...
- Random Point in Triangle【随机数解决期望值问题】
Random Point in Triangle 题目链接(点击) 题目描述 Bobo has a triangle ABC with A(x1,y1),B(x2,y2)A(x1,y1),B(x2,y ...
- 【Android】使用Appium+python控制真机,碰到的问题以及处理(持续更新)
问题: selenium.common.exceptions.WebDriverException: Message: A new session could not be created. (Ori ...
- CentOS7.5搭建ES6.2.4集群与简单测试
一 简介 Elasticsearch是一个高度可扩展的开源全文搜索和分析引擎.它允许您快速,近实时地存储,搜索和分析大量数据.它通常用作支持具有复杂搜索功能和需求的应用程序的底层引擎/技术. 下载地址 ...
- 关联函数-web_reg_save_param
int web_reg_save_param(const char *ParamName,<List of Attributes>,LAST) 返回值:成功时返回LR_PASS,失败时返回 ...