P3202 [HNOI2009]通往城堡之路

题目描述

听说公主被关押在城堡里,彭大侠下定决心:不管一路上有多少坎坷,不管城堡中的看守有多少厉害,不管救了公主之后公主会不会再被抓走,不管公主是否漂亮、是否会钟情于自己,他将义无反顾地朝着城堡前进。

可是,通往城堡的路上出现了一些情况。抽象地说,假象地图在二维平面的第一象限。在每个横轴的x位置上有一个高为hx的支撑点,如果彭大侠没有跳到支撑点上,那么他就会掉下去,牺牲在路途。

开始时彭大侠在起点(1,h1)处,而城堡的入口在(n,hn)处。彭大侠每次可以从支撑点(x,hx)跳到支撑点(x+1,hx+1)。但是彭大侠每次的跳跃能量只有d,也就是说,每次跳跃必须满足条件|hx+1-hn|<=d。换句话说,如果两个相邻支撑点的纵向落差大于d,那么彭大侠就无法跳跃了!幸运的是,彭大侠还有一个杀手锏。 在起点处,他可以花一个金币,把某个支撑点升高1个单位,或者降低1个单位。但是,起点处和城堡入口处的支撑点高度不能改变,并且一旦离开起点彭大侠就无法使用该杀手锏。

彭大侠被告知100个金币可兑换一单位生命。于是他希望通过少花金币来保存更多单位的生命。

他终于找到了你这位热心的高手,请你帮他规划一下以便耗费尽量少的金币来到达城堡。

输入输出格式

输入格式:

文件第一行包含一个整数m(m<=5),表示问题求解次数。接下来的2m行依次表示每次求解的输入数据块。每个输入数据块占2行,其中第一行包含两个整数n和d,分别表示从起点到城堡入口处必须经过的支撑点数和每次跳跃允许的最大纵向落差,n和d之间用空格隔开,输入数据保证2<=n<=5000,0<=d<=109;第二行包含用空格隔开的n个非负整数h1、h2、...、hn,其中hi(1<=i<=n)表示第i个支撑点的高度,特别地,h1表示彭大侠出发时所在支撑点的高度,hn表示城堡入口所在支撑点的高度,输入数据保证对所有1<=i<=n有0<=hi<=109。

输出格式:

有m行,第I(1<=I<=m)行表示第I次求解时彭大侠到达城堡必须耗费的最少金币数量。若无论怎样使用杀手锏他都无法到达城堡,则输出impossible。输入数据保证答案在int64范围之内。

输入输出样例

输入样例#1: 复制

3

10 2

4 5 10 6 6 9 4 7 9 8

3 1

6 4 0

4 2

3 0 6 3

输出样例#1: 复制

6

impossible

4

说明

对样例中的第一个输入数据块,d=2,把第三个支撑点降低3个单位,把第六个支撑点降低1个单位,把第七个支撑点升高2个单位,原序列变成:4 5 7 6 6 8 6 7 9 8,这时任意相邻支撑点的纵向落差没有超过2,彭大侠可以到达城堡!

对样例中的第二个输入数据块,d=1,这时不管怎样调节第二个支撑点的高度,都无法使任意相邻支撑点的纵向落差不超过1。

对样例中的第三个输入数据块,d=2,这时,把第二个支撑点升高1个单位,把第三个支撑点降低3个单位就满足条件了。

【数据规模】

 20%     n<=100

 40%     n<=1000

100% n<=5000

题解

这么神仙的题目为什么不是黑题啊qwq

我感觉[HNOI2012]取石头游戏没这个难啊。

这个贪心不看题解,真的有人想得到这么贪心吗?

首先我们造一组伪解,以最坏的情况考虑,定义

\(b[1]=a[1];\)然后\(b[]\)依次减少\(d.\)

因为我们是这样定义的了,所以我们不再需要降低任意一个区间。

为什么?

因为最后是要让\(b[n]=a[n]\)的,

我们考虑依次提高后缀,为什么是提高后缀,因为我们这样\(O(n)\)考虑一遍的话,可以考虑到是否提高每一个点。

又因为设\(s\)为当前后缀内的\(a[i]>b[i]\),那么当\(s\)为正时,我们提高这个后缀就一定是优的。而提高这个区间的值为这个区间内最小的(\(a[i]-b[i]\))(这时的\(a[i]>b[i]\)),这样可以使这个点提高到正常高度,因此我们最多提高\(n-1\)次,又每次给区间加上提高的值为\(O(n)\)。所以总复杂度为\(O(n^2)\)。

其中因为我们每次只增加最小值,那么我们当前加入的值一定是让答案更优的,如果下降就只会让答案更劣。

Ps:每次加上的提高值为\(min(a[i]-b[i],b[j-1]+d-b[j]);\)(j为后缀的开头,我们要保证提高的合法性,不能跳不到了。)

Code

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1e6+5;
ll n,d,ans,a[N],b[N]; ll read(){
ll x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
} void solve(){
n=read();d=read();ans=0;
for(ll i=1;i<=n;i++)a[i]=read();
if(abs(a[1]-a[n])>(n-1)*d)
{cout<<"impossible"<<endl;return ;}
b[1]=a[1];
for(ll i=2;i<=n;i++)b[i]=b[i-1]-d;
while(b[n]!=a[n]){
ll mx=-1e9,j,mn=1e9,s=0,addx=1e9;
for(ll i=n;i>=2;i--){
if(a[i]>b[i])s++,mn=min(mn,a[i]-b[i]);
else s--;
if(s>mx&&b[i]<b[i-1]+d){
mx=s;j=i;addx=mn;
}
}
addx=min(addx,b[j-1]+d-b[j]);
for(ll i=j;i<=n;i++)b[i]+=addx;
}
for(ll i=1;i<=n;i++)ans+=abs(a[i]-b[i]);
cout<<ans<<endl;
} int main(){
ll T=read();
while(T--)solve();
return 0;
}

[luogu] P3202 [HNOI2009]通往城堡之路(贪心)的更多相关文章

  1. P3202 [HNOI2009]通往城堡之路 神仙题

    这个题不是坑人吗...写个tarjan标签,然后拿这么个神仙题来搞...代码有点看不懂,有兴趣的可以去洛谷题解区看看,懒得想了. 题干: 题目描述 听说公主被关押在城堡里,彭大侠下定决心:不管一路上有 ...

  2. 【BZOJ1484】[HNOI2009]通往城堡之路 (贪心)

    [BZOJ1484][HNOI2009]通往城堡之路 (贪心) 题面 BZOJ 洛谷 题解 我大概是不会的. 大概是,首先把所有的人全部弄成最低的值,再一次次拔高一个后缀. 其他的全是抄的,百度随便找 ...

  3. [HNOI2009]通往城堡之路

    题目描述 听说公主被关押在城堡里,彭大侠下定决心:不管一路上有多少坎坷,不管城堡中的看守有多少厉害,不管救了公主之后公主会不会再被抓走,不管公主是否漂亮.是否会钟情于自己,他将义无反顾地朝着城堡前进. ...

  4. BZOJ1484 [HNOI2009]通往城堡之路

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  5. [luogu] P3333 [ZJOI2013]丽洁体(贪心)

    P3333 [ZJOI2013]丽洁体 题目描述 平时的练习和考试中,我们经常会碰上这样的题:命题人给出一个例句,要我们类比着写句子.这种往往被称为仿写的题,不单单出现在小学生的考试中,也有时会出现在 ...

  6. [Luogu 2817]宋荣子的城堡

    Description saruka有一座大大的城堡!城堡里面有n个房间,每个房间上面都写着一个数字p[i].有一天,saruka邀请他的小伙伴LYL和 MagHSK来城堡里玩耍(为什么没有妹子),他 ...

  7. Luogu P2114[NOI2014]起床困难综合症 【贪心/位运算】By cellur925

    题目传送门 所以NOI的题现在简单惹? 30分做法:枚举开始的权值,n²过掉. 100分做法:竟然是贪心qwq.因为我们的计算背景是二进制下,所以我们贪心地想让每一位都是1.我们现在需要解决的问题,就 ...

  8. [Luogu] P2817 宋荣子的城堡

    题目描述 saruka有一座大大的城堡!城堡里面有n个房间,每个房间上面都写着一个数字p[i].有一天,saruka邀请他的小伙伴LYL和MagHSK来城堡里玩耍(为什么没有妹子),他们约定,如果某一 ...

  9. [luogu] P3210 [HNOI2010]取石头游戏(贪心)

    P3210 [HNOI2010]取石头游戏 题目描述 A 公司正在举办一个智力双人游戏比赛----取石子游戏,游戏的获胜者将会获得 A 公司提供的丰厚奖金,因此吸引了来自全国各地的许多聪明的选手前来参 ...

随机推荐

  1. Problem 4

    Problem 4 # Problem_4 """ A palindromic number reads the same both ways. The largest ...

  2. C# List源码分析(二)

    常用操作的复杂度分析 Contains 该方法是一个O(n)的方法,是根据顺序依次遍历整个列表的,观看源码,跟JAVA还是有不少分别的,在上一篇中就有发现,因为C#对Primitive类型是有处理的, ...

  3. C#实现简单的串口通信

    前言 本着学习研究的态度,用c#语言实现简单的串口通信工具. 一.串口通信原理 串口通信 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节.尽管比 ...

  4. 06005_Jedis入门

    1.Jedis介绍 (1)Redis不仅是使用命令来操作.现在基本上主流的语言都有客户端支持,比如Java.C.C#.C++.PHP.Node.js.Go等: (2)在官方网站里列有一些Java的客户 ...

  5. 02023_Arrays类的方法练习

    1.定义一个方法,接收一个数组,数组中存储10个学生考试分数,该方法要求返回考试分数最低的后三名考试分数. public static int[] method(double[] arr){ Arra ...

  6. CF914A Perfect Squares

    CF914A Perfect Squares 题意翻译 给定一组有n个整数的数组a1,a2,…,an.找出这组数中的最大非完全平方数. 完全平方数是指有这样的一个数x,存在整数y,使得x=y^2y2  ...

  7. 动态为TextView控件设置drawableLeft图标,并设置间距

    效果图: 重要属性: textView.setCompoundDrawablePadding(4);//设置图片和text之间的间距 textView.setPadding(-5, 0, 0, 0); ...

  8. Android仿IOS的AssistiveTouch的控件EasyTouch实现

    概述: 之前我听到过一则新闻,就是说Ipone中的AssistiveTouch的设计初衷是给残疾人使用的. 而这一功能在亚洲(中国)的使用最为频繁. 虽不知道这新闻的可靠性,但无庸置疑的是它的确给我们 ...

  9. VMware虚拟机无法识别U盘解决方式

    1. 本机情况: Winxp操作系统(相同应该适用于win7),VMware虚拟机.虚拟机版本号:VMware 10.安装Ubuntu14.04.现要求在主机上插入U盘.在虚拟机中显示. 2. 遇到问 ...

  10. 51NOD 1686 第K大区间 二分

    第k大区间   定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. Input   第一行两个数n和k(1<=n<=100000,k<=n* ...