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

Input

51 1 1 1 1

Output

1 2 2 

Input

31 2 3

Output

0 2 

Input

51 2 3 2 2

Output

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就可以考虑建房子了,这个情况就比较简单了

细节见代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 const int maxn = 5000+10;
 7 int h[5050];
 8 int dp[5050][5050][2];
 9 int main(){
10     memset(dp,0x3f,sizeof(dp));
11     dp[0][0][0]= dp[1][1][1] = dp[1][0][0] =0; //初始化,这里其实省了一个循环,把dp[i][0][0]放到下面的dp循环里了
12     h[0]=0x3f3f3f3f; //设为无限大,是为了不干扰后面的操作,而且h[0]一定会出现
13     int n;scanf("%d",&n);
14     for(int i=1;i<=n;++i){
15         scanf("%d",&h[i]);
16     }
17     for(int i=2;i<=n;++i){
18         dp[i][0][0]=dp[i-1][0][0];  //前面省的初始化化放到这里了
19         for(int j=1;j<=(i+1)/2;++j){  //这个括号可能有点长,但其实并不太复杂
20             dp[i][j][1]=min(dp[i-2][j-1][0]+max(0,h[i-1]-h[i]+1),   //max函数,其实是代替了if,如果h[i-1]-h[i]+1小于0,说明i-1更矮,就不用挖掉了
21                            dp[i-2][j-1][1]+max(0,h[i-1]-min(h[i],h[i-2])+1));  //h[i]和h[i-2],哪个高出来得更多,就挖哪个,这样另一个就也比i-1矮了
22             dp[i][j][0]=min(dp[i-1][j][0],
23                            dp[i-1][j][1]+max(0,h[i]-h[i-1]+1)); //上面那个理解了这个就没问题了
24         }
25     }
26     for(int i=1;i<=(n+1)/2;++i){
27         printf("%d ", min(dp[n][i][0],dp[n][i][1]));
28     }
29     return 0;
30 }

写了这么多,你会明白的对吧(*?▽?*)

原文地址:https://www.cnblogs.com/hhhhalo/p/12688633.html

时间: 2024-10-13 09:57:38

Hills——一道转移方程很“有趣”的线性DP的相关文章

LA 4256 Salesmen 线性dp

// LA 4256 Salesmen 线性dp // // 像LCS和LIS问题类似,因为每次修改一个值,都是根据 // 前一个值决定的,那么最后一个结尾的数字肯定要作为 // 状态,而长度作为状态是一目了然的 // // d[i][j]表示长度为i,最后以j结尾的数组修改的最小次数 // // 则状态转移方程为 // // d[i][j] = min(d[i][j],d[i-1][k]+(j,k是否相同或者相邻?0:1)); // // 个人感觉还是比较明显的,最后的答案就是min(d[L]

线性DP POJ2279 Mr.Young&#39;s Picture Permutations

Mr. Young's Picture Permutations Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1128   Accepted: 562 Description Mr. Young wishes to take a picture of his class. The students will stand in rows with each row no longer than the row behin

【HDU-1051】Wooden Sticks 【线性DP】

一堆n根木棍.每个棒的长度和重量是预先已知的.这些木棒将由木工机械一一加工.机器需要准备一些时间(称为准备时间)来准备处理木棍.设置时间与清洁操作以及更换机器中的工具和形状有关.木工机械的准备时间如下: (a)第一个木棍的准备时间为1分钟. (b)在处理长度为l和重量为w的棒之后,如果l <= l'并且w <= w',则机器将不需要设置长度为l'和重量w'棒的设置时间.否则,将需要1分钟进行设置.您将找到处理给定的n根木棍的最短准备时间.   3 5 4 9 5 2 2 1 3 5 1 4 3

codevs 3342 绿色通道 (二分+线性DP)

codevs 3342 绿色通道 http://codevs.cn/problem/3342/ 难度等级:黄金 题目描述 Description <思远高考绿色通道>(Green Passage, GP)是唐山一中常用的练习册之一,其题量之大深受lsz等许多oiers的痛恨,其中又以数学绿色通道为最.2007年某月某日,soon-if (数学课代表),又一次宣布收这本作业,而lsz还一点也没有写…… 高二数学<绿色通道>总共有n道题目要写(其实是抄),编号1..n,抄每道题所花时间

uva 11552 Fewest Flops 线性dp

// uva 11552 Fewest Flops // // 二维线性dp // // 首先,在该块必须是相同的来信.首先记录每块有很多种书 // 称为是counts[i]; // // 订购f[i][j]它代表前i字母j为结尾的最小分块数 // // 假设第i块的開始字母与第i-1块的结束字母同样 // f[i][j] = min(f[i][j],f[i-1][k] + counts[i] - 1); // // 否则 // // f[i][j] = min(f[i][j],f[i-1][k

POJ 1958 Strange Towers of Hanoi (四塔问题,线性dp,记忆化搜索)

题目分析:四柱汉诺塔.由于题目已经给出了求解方法,直接写代码即可.下面总结一下,四塔问题. 感谢这篇文章的作者,点这里就到,总结的很好.直接贴过来~ 四塔问题:设有A,B,C,D四个柱子(有时称塔),在A柱上有由小到大堆放的n个盘子. 今将A柱上的盘子移动到D柱上去.可以利用B,C柱作为工作栈用,移动的规则如下: ①每次只能移动一个盘子. ②在移动的过程中,小盘子只能放到大盘子的上面. 设计并实现一个求解四塔问题的动态规划算法,并分析时间和空间复杂性. 算法思想: 用如下算法移动盘子(记为Fou

动态规划——线性dp

我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模型,例如最长上升子序列(LIS).最长公共子序列(LCS).最大子序列和等,那么首先我们从这几个经典的问题出发开始对线性dp的探索. 首先我们来看最长上升子序列问题. 这个问题基于这样一个背景,对于含有n个元素的集合S = {a1.a2.a3……an},对于S的一个子序列S‘ = {ai,aj,ak

POJ 2355 Railway tickets (线性dp)

OJ题目 :click here~ 题目分析:X为距离 , 当0<X<=L1, 票价为C1. L1<X<=L2 ,票价为C2.L2<X<=L3,票价为C3.给每段车站时间的距离,求某两个车站之间的总票价的最小值. 设dp[ i ] 为到车站 i 的最少票价 . 则转移方程为dp[ i ] = min(dp[ j ] + 从j 到 i 的票价),j 为所有可以直接到 i 的车站. 要注意第一个数字 大于 第二个数字的情况.的确,题目没有说,从a 到 b.只说了a,b之间.

HDU 4293 Groups (线性dp)

OJ题目:click here~~ 题目分析:n个人分为若干组 , 每一个人描写叙述其所在的组前面的人数和后面的人数.求这n个描写叙述中,最多正确的个数. 设dp[ i ] 为前i个人的描写叙述中最多正确的个数,则dp[ n ] 为要求的.num[ i ][ j ]  保存说前面有i个人 , 后面有j个人的人数,显然num[ i ][ j ]不超过n - i - j; 转移方程dp[ i ] = max(dp[ i ] , dp[ j ]  + num[ j ][ n - i ])  ,详解见代