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,最大子序 ...
随机推荐
- Java实现One-way traffic(单向交通)
One-way traffic In a certain town there are n intersections connected by two- and one-way streets. T ...
- java关键字static用法详解
java中有53个关键字,其中包含2个保留字,这篇文章主要介绍一下static这个关键字. static在java中算是一个比较常见的关键字,有着多种用法,因此很有必要好好地了解一番. 一.定义 st ...
- ModelArts准备工作
说明: 本文是一个ModelArts准备工作文档,适用于初次使用ModelArts的用户.使用ModelArts之前,需要做如下工作:注册华为云账号.完成ModelArts全局配置.以及熟悉OBS相关 ...
- 环境篇:CM+CDH6.3.2环境搭建(全网最全)
环境篇:CM+CDH6.3.2环境搭建(全网最全) 一 环境准备 1.1 三台虚拟机准备 Master( 32g内存 + 100g硬盘 + 4cpu + 每个cpu2核) 2台Slave( 12g内存 ...
- 【快手初面】要求3个线程按顺序循环执行,如循环打印A,B,C
[背景]这个题目是当时远程面试时,手写的题目.自己比较惭愧,当时写的并不好,面试完就又好好的完善了下. 一.题意分析 3个线程要按顺序执行,就要通过线程通信去控制这3个线程的执行顺序. 而线程通信的方 ...
- Vue项目实战之改动饿了吗购物小球动画
html:没有写v-on: afterEnter函数了,因为执行不到,原因是enter的done: <div class="ball-container"><tr ...
- @atcoder - AGC026F@ Manju Game
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个含 N 个数的序列,Alice 与 Bob 在博弈.Al ...
- Magic Line【坐标点排序方法】
Magic Line 题目链接(传送门) 来源:牛客网 题目描述 There are always some problems that seem simple but is difficult to ...
- 基于移动最小二乘法的点云曲面拟合(python)
1.移动最小二乘法介绍 为了更好地对数据量大且形状复杂的离散数据进行拟合,曾清红等人[1]开发出一种新的算法——移动最小二乘法.这种新的最小二乘算法为点云数据的处理提供了新的方法.使用点云数据拟合曲面 ...
- BUAA_OO_2020_Unit2_总结博客
BUAA_OO_2020_Unit2_总结 2020年春季学期第八周,OO第二单元落下帷幕,三次多线程任务作罢,萌新在OO的世界里又迈出了艰难但有意义的一步,下作总结: 一.三次作业设计策略 回顾三次 ...