Easy Climb UVA - 12170 滚动dp +离散化+ 单调队列优化
E.Easy Climb
Somewhere in the neighborhood we have a very nice mountain that gives a splendid view over the surrounding area. There is one problem though: climbing this mountain is very difficult, because of rather large height differences. To make more people able to climb the mountain and enjoy the view, we would like to make the climb easier.
To do so, we will model the mountain as follows: the mountain consists of n adjacent stacks of stones, and each of the stacks is hi high. The successive height differences are therefore hi+1-hi (for 1 ≤ i ≤ n-1). We would like all absolute values of these height differences to be smaller than or equal to some number d.
We can do this by increasing or decreasing the height of some of the stacks. The first stack (the starting point) and the last stack (the ending point) should remain at the same height as they are initially. Since adding and removing stones requires a lot of effort, we would like to minimize the total number of added stones plus the total number of removed stones. What is this minimum number?
Input
On the first line one positive number: the number of testcases, at most 100. After that per testcase:
One line with two integers n (2 ≤ n ≤ 100) and d (0 ≤ d ≤ 109): the number of stacks of stones and the maximum allowed height difference.
One line with n integers hi (0 ≤ hi ≤ 109): the heights of the stacks.
Output
Per testcase:
One line with the minimum number of stones that have to be added or removed or “impossible” if it is impossible to achieve the goal.
Sample Input
3
10 2
4 5 10 6 6 9 4 7 9 8
3 1
6 4 0
4 2
3 0 6 3
Sample Output
6
impossible
4
The 2008 ACM Northwestern European Programming Contest
题意:给了n个堆的高度,要求改变堆的高度,首尾不可改变,使得队列的任意相邻的两数之差<=d,求最小代价
题解:
首先,如果数据范围很小的话 可以直接定义dp[i][j]表示处理完前i个高度后最后一个高度为b[j]的最小花费。 这样定义状态正确性是显而易见的。
然而 这里的d范围是10^9 显然不允许我们这么暴力的去枚举每一个状态。
所以需要去剪枝。 观察到最多只有100个高度, 却分布在1e9的范围里
肯定有很多状态是不会被用到的,应该要想到用离散化缩小范围。
首先,考虑只有3个值的情况:h1, h2, h3。那么根据题意,h2的范围应该在区间[h1-d,h1+d]和[h3-d,h3+d]的交集,即h1应该在[max(h1,h3)-d,min(h1,h3)+d]之间。如果这个区间是空集,即abs(h3-h1)>(3-1)*d,那么自然无解,否则:
1、如果h2就在区间内部,那么不需要修改;
2、如果h2<max(h1,h3)-d,那么就修改为交集的区间下界max(h1,h3)-d;
3、如果h2>min(h1,h3)+d,那么就修改为交集区间的上界min(h1,h3)+d。
可以发现,在这个简单的问题中,h2的最优修改方案只有这3种情况。并且我们还发现了,如果要修改,修改后的高度一定是如hp+k*d的形式。---离散化缩小范围
离散化缩小范围后呢,
下面需要想的就是状态转移方程了。
dp[i][j]=min(dp[i-1][k])+abs(x[j]-h[i]);// j-d<=k<=j+d;
一般单调队列有头,尾两个指针来维持单调性,这里只用一个头指针就完成普通单调队列的写法,在本题中 直接把b[] 数组当单调队列来用了
首先
具体做法是:
1.先维护窗口左边界,别让指针k超出了窗口,如果bk] < b[j] - d那么就k++ (因为b数组是从小到大已经排好序的),然后在不超出右边界b[j]+d 的前提下,如果dp[i][k+1] <= dp[i][k],那么k++;
为什么这样是对的的? 好像和之前说的优先队列一点也不一样啊! 其实是一样的操作,仔细回想维护优先队列时是怎么操作的 :用两个指针front、rear 先更新左边界,防止当前位置超出区间边界,一旦超出就front++; 然后每次新加进来一个值就要看看当前队列最右端的元素与新值的大小,如果大于新值那么就rear--,将无用的元素请出队列 ,直到小于新值,就将新值加入, 然而其实上边那个用一个指针的方法是如出一辙的,只不过将删除无用值这一步放到了求最小值时,也就是更新k时 。
#include<iostream>
#include<algorithm>
#include<math.h>
#define ll long long
#define mx 999999999999
using namespace std;
ll a[],b[],dp[][];// dp[i][j]表示 处理完前i座山后 最后一座山的高度为b[j]的最小花费;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,d;
cin>>n>>d;
for(int i=;i<n;i++)
cin>>a[i];
if(abs(a[n-]-a[])>(n-)*d)
{
cout<<"impossible"<<endl;
continue;
}
ll cnt=;
for(int i=;i<n;i++)//离散化,处理后将山所有可能的改变值存在b数组
{
for(int j=;j<n;j++)
{
b[cnt++]=a[i]+j*d;
b[cnt++]=a[i]-j*d;
}
}
int m;
sort(b,b+cnt);
m=unique(b,b+cnt)-b;
for(int i=;i<m;i++)//初始化dp
{
dp[][i]=mx;
if(b[i]==a[])
dp[][i]=;
}
for(int i=;i<n;i++)
{
int k=;//单调队列头指针
for(int j=;j<m;j++)//如果山峰的高度要改变为b[k],那么b[k]的范围为[b[j]-d,b[j]+d],并且要达到最优,要么改变为b[k]-d,要么改变为b[k]+d
{
while(k<m&&b[k]<b[j]-d)//改变为区间下界值b[j]-d;找到b[k]>=b[j]-d就退出
k++;
while(k+<m&&b[k+]<=b[j]+d&&dp[i-][k+]<=dp[i-][k])//改变为区间上界值b[j]+d
k++;
if(dp[i-][k]==mx)
dp[i][j]=mx;
else
dp[i][j]=dp[i-][k]+abs(b[j]-a[i]);
}
}
for(int i=;i<m;i++)
{
if(b[i]==a[n-])
cout<<dp[n-][i]<<endl;
}
}
}
Easy Climb UVA - 12170 滚动dp +离散化+ 单调队列优化的更多相关文章
- 洛谷P3975 跳房子 [DP,单调队列优化,二分答案]
题目传送门 跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一 ...
- Codeforces 487B Strip (ST表+线段树维护DP 或 单调队列优化DP)
题目链接 Strip 题意 把一个数列分成连续的$k$段,要求满足每一段内的元素最大值和最小值的差值不超过$s$, 同时每一段内的元素个数要大于等于$l$, 求$k$的最小值. 考虑$DP$ 设$ ...
- HDU 4374 One hundred layer DP的单调队列优化
One hundred layer Problem Description Now there is a game called the new man down 100th floor. The ...
- P2034 选择数字——线性dp(单调队列优化)
选择数字 题目描述 给定一行 \(n\) 个非负整数 \(a[1]...a[n]\) .现在你可以选择其中若干个数,但不能有超过 \(k\) 个连续的数字被选择.你的任务是使得选出的数字的和最大. 输 ...
- ZOJ2067 经典 DP(单调队列优化)
题目:一个由‘.’和‘#’组成矩形,统计里面'.'组成的矩形的个数. 点击打开链接 自己写挂了,懒得搞了 #include <stdio.h> #include <string.h& ...
- [小明打联盟][斜率/单调队列 优化dp][背包]
链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...
- [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp
Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...
- 2018.09.10 bzoj1499: [NOI2005]瑰丽华尔兹(单调队列优化dp)
传送门 单调队列优化dp好题. 这题其实很简单. 我们很容易想到一个O(T∗n∗m)" role="presentation" style="position: ...
- bzoj 1499 [NOI2005]瑰丽华尔兹——单调队列优化dp
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1499 简单的单调队列优化dp.(然而当时却WA得不行.今天总算填了坑) 注意滚动数组赋初值应 ...
随机推荐
- springmvc启动加载指定方法
官网: https://docs.oracle.com/javaee/7/api/javax/annotation/PostConstruct.htmlblog:https://blog.csdn.n ...
- 删除hdfs上的内容报错:rm: Cannot delete /wxcm/ Name node is in safe mode.
问题:在执行删除hdfs上的内容时(hdfs dfs -rm -f -r -skipTrash /wxcm)报错:rm: Cannot delete /wxcm/ Name node is in sa ...
- 【PAT甲级】1016 Phone Bills (25 分)(结构体排序)
题意: 输入24个正整数代表从0到23每个小时通话一分钟花费的美分.输入一个正整数N(<=1000),然后输入N组字符串,每个字符串包含客户的名字和通话的时刻以及打出或者挂断的状态. 按照字典序 ...
- Lesson 11 How to grow old
What, accoroding to the author is the best way to overcome the fear of death as you get older? Some ...
- CentOS安装后的第一步:配置IP地址
有关于centos7获取IP地址的方法主要有两种,1:动态获取ip:2:设置静态IP地址 在配置网络之前我们先要知道centos的网卡名称是什么,centos7不再使用ifconfig命令,可通过命令 ...
- ADV-299 宰羊 (java,过了30%)
问题描述 炫炫回了内蒙,肯定要吃羊肉啦,所有他家要宰羊吃. 炫炫家有N只羊,羊圈排成一排,标号1~N.炫炫每天吃掉一只羊(这食量!其实是放生啦),吃掉的羊的邻居会以为它被放生了,然后又会告诉他们的邻居 ...
- 《C Primer Plus(第6版)(中文版)》普拉达(作者)epub+mobi+azw3
内容简介 <C Primer Plus(第6版)中文版>详细讲解了C语言的基本概念和编程技巧. <C Primer Plus(第6版)中文版>共17章.第1.2章介绍了C语言编 ...
- Linux安装nginx的环境要求
# Linux下切记不能乱删东西!我把pcre强制删除后,什么命令都不能使用了,系统奔溃,血的教训! nginx是C语言开发,建议在linux上运行,本教程使用Centos6.4作为安装环境. 一. ...
- Thymeleaf--起步
Spring官方支持的服务的渲染模板中,并不包含jsp.而是Thymeleaf和Freemarker等,而Thymeleaf与SpringMVC的视图技术,及SpringBoot的自动化配置集成非常完 ...
- Java导出Excel(项目实战Demo)
Controller 层 /** * 考勤机刷卡明细导出Excel * * @throws Exception */ // @RequiresPermissions("report:Expo ...