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实现 LeetCode_0048_RotateImage
package javaLeetCode.medium; public class RotateImage_48 { public static void main(String[] args) { ...
- java实现蓝桥杯约瑟夫环
n 个人的编号是 1~n,如果他们依编号按顺时针排成一个圆圈,从编号是1的人开始顺时针报数. (报数是从1报起)当报到 k 的时候,这个人就退出游戏圈.下一个人重新从1开始报数. 求最后剩下的人的编号 ...
- Java实现第九届蓝桥杯分数
分数 题目描述 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + - 每项是前一项的一半,如果一共有20项, 求这个和是多少,结果用分数表示出来. 类似: 3/2 当然,这只是加了前2项而 ...
- transport方式连接Elasticsearch6.2.3
连接ES有3中方式: ①transport方式 ②rest方式 ③JEST方式(第三方) 我自己项目使用第一种方式,代码和配置如下: 1.引入依赖 <dependency> <gro ...
- javaScript的执行机制-同步任务-异步任务-微任务-宏任务
一.概念理解 1.关于javascript javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变.所以一切javascr ...
- pytorch入门2.1构建回归模型初体验(模型构建)
pytorch入门2.x构建回归模型系列: pytorch入门2.0构建回归模型初体验(数据生成) pytorch入门2.1构建回归模型初体验(模型构建) pytorch入门2.2构建回归模型初体验( ...
- 利用Jackson将数据转换为Json
1.确保相关依赖导入 2.配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app ...
- JVM内存结构详解
从java编程语言说起... 1. Java编程语言简介 1.1 编程语言概述 系统级和应用级 系统级:C,C++,go,erlang 应用级:C#,Java,Python,Perl,Ruby,php ...
- 记PHP下载大文件失败的一次坑
说明 php提供文件的储存和下载,nginx作为web服务器,fpm做解析. 现象 当下载一个5M大小的图片时,总提示下载失败,或下载下来的文件不完整,仅显示部分图像(每次下载不一样) php下载相关 ...
- 设计模式:JDK和Spring中常见的设计模式
设计模式 总结 类 工厂模式 封装创建过程,只对结果负责 BeanFactory.Calender 单例模式 全局唯一 ApplicationContext.Calender 原型模式 多重影分身之术 ...