来了来了。


题目:

给你n个数,你一次操作可以把某一个数-1(可以减为负数),你的目标是使任意的k个数严格小于它旁边的两个数(第一个数只用严格小于第二个数,第n个数只用严格小于第n-1个数),问最少需要几次操作。k是不确定的,请输出1<=k<=n/2(向上取整)时的答案。

输入格式:

第一行一个正整数n

第二行n个正整数ai

输出格式:

一行 1<=k<=n/2 个数,第i个数代表k=i时的答案

数据范围:

1 ≤ n ≤ 5000

1 ≤ ai ≤ 100000

输入 #1复制

5
1 1 1 1 1
输出 #1复制

1 2 2 
输入 #2复制

3
1 2 3
输出 #2复制

0 2 

思路:

看到这道题的第一眼,我想到了一道题,2018noipD1T1铺设道路(链接:https://www.luogu.com.cn/problem/P5019),看起来十分相似,于是这道题想用朴素的贪心写,结果果然不对,两道题的区别还是很大,贪心的正确性无法保证,所以还是回来老老实实的写动归。

我们设定一个三维数组f,f[i][j][0]表示前i座山,修建j座房子,且第i座山没有建房子的代价,f[i][j][1]表示前i座山,修建j座房子,且第i座山建有房子的代价。

通过简单的模拟我们可以得到,(1)f[i][j][0]会从f[i-1][j][0](直接从前一个状态搬过来,前一座山和这座山都不建房子,抹油代价)和f[i-1][j][1](前一座山已经建了房子,那么就要使这座山的高度低于前一座山的高度,代价为max(0,a[i]-a[i-1]+1),有0是因为可能这座山的高度原来就低于前一座山的高度)转移过来,转移方程为:f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]+max(0,a[i]-a[i-1]+1))   (2)f[i][j][1]的处理要比f[i][j][0]的处理相对复杂,在此我们明确一个观点,相邻的两座山不可能都建房子,并且在考虑这座山是否建房子的时候,可以只考虑这座山之前的状态,而不去考虑这座山之后的状态,这座山之后的状态我们可以在之后再处理,因此,f[i][j][1]可以从f[i-2][j-1][0]转移过来,因为第i-2座山没有建房子,所以第i-1座山的高度没有变化,代价为max(0,a[i]-a[i-1]+1)。f[i][j][1]同样可以从f[i-2][j-1][1]转移过来,因为第i-2座山已经建有房子,所以第i-1座山的高度可能会有变化,因此,总代价为:max(0,a[i-1]-(a[i-2],a[i])+1)(大家思考一下,为什么这里总代价不是:max(0,a[i-1]-min(0,a[i-1]-a[i-2]+1)-a[i]+1)) 答案(先思考再看答案):因为第i-1座山的高度一定比第i-2和i座山低,而这样做只能保证第i-1座山的高度低于第i-2座山的高度,无法保证第i-1座山的高度低于第i座山的高度,因此,我们也可以改成:max(max(0,a[i-1]-a[i]+1),max(0,a[i-1]-a[i-2]+1)) 贼长)

代码:

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=5e3+,maxe=5e3+,INF=0x3f3f3f3f;
int n,m,a[maxn],f[maxn][maxn][],ans;
inline int read(){
int s=,t=;
char ch=getchar();
while(ch<''||ch>''){if(ch=='-')t=-;ch=getchar();}
while(ch>=''&&ch<='')s=s*+ch-'',ch=getchar();
return s*t;
}//朴素快读
int main(){
freopen("a.in","r",stdin);
n=read();
for(int i=;i<=n;i++)a[i]=read();
a[]=INF;
memset(f,0x3f,sizeof(f));
f[][][]=f[][][]=f[][][]=;//初始化
for(int i=;i<=n;i++){
f[i][][]=f[i-][][];
for(int j=;j<=(i+)/;j++){//这里我测了一下,不管是用floor+1还是用ceil都不行,神奇
f[i][j][]=min(f[i-][j-][]+max(,a[i-]-a[i]+),f[i-][j-][]+max(max(,a[i-]-a[i]+),max(,a[i-]-a[i-]+)));
f[i][j][]=min(f[i-][j][],f[i-][j][]+max(,a[i]-a[i-]+));
}
//cout<<floor(i/2)+1<<" "<<(i+1)/2<<endl;
}
for(int i=;i<=(n+)/;i++)cout<<min(f[n][i][],f[n][i][])<<" ";
return ;
}

嘤嘤嘤,溜了

【线型DP】CF1012C Hills 小山坡的更多相关文章

  1. 【线型DP】洛谷P2066 机器分配

    [线型DP]洛谷P2066 机器分配 标签(空格分隔): 线型DP [题目] 题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配 ...

  2. CF1012C Hills 题解【DP】

    思路还是比较简单的 dp 吧,但是就是想不出来-甚至类似的方程都被自己推翻了 Description Welcome to Innopolis city. Throughout the whole y ...

  3. [bzoj3209][花神的数论题] (数位dp+费马小定理)

    Description 背景众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦.描述话说花神这天又来讲课了.课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了. ...

  4. 洛谷 CF1012C Hills (动态规划)

    题目大意:有n个山丘 , 可以在山丘上建房子 , 建房子的要求是 : 该山丘的左右山丘严格的矮于该山丘 (如果有的话),你有一架挖掘机,每单位时间可以给一个山丘挖一个单位的高度,问你想要建造 1,2, ...

  5. 【线型DP模板】最上上升子序列(LIS),最长公共子序列(LCS),最长公共上升子序列(LCIS)

    BEGIN LIS: 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序 ...

  6. 【线型DP】【LCS】UVA_10635 Prince and Princess

    嘤嘤嘤,我又来了,刚A完就写,这个沙雕题有丶恶心.                  ???时间4.11发现所有表情包都莫得了 题目: In an n×n chessboard, Prince and ...

  7. CF1012C Hills

    显然的DP是,dp[i][j][val] val是1e6的 简化 发现,其实决策很有限,最优解的i-1的val选择有限 题解 这里的一个trick是,f[i][j][0]转移不考虑a[i]和a[i-1 ...

  8. 线性dp——cf1012C好题

    比较套路的dp题 /* dp[i][j][0|1]:前i座山盖了j座房子,第i座不盖|盖 dp[i][j][0]=min( dp[i-1][j][0] , dp[i-1][j][1]+max(0,a[ ...

  9. 洛谷 CF1012C Hills(动态规划)

    题目大意: 有几座山,如果一座山左右两边的山比它矮,那么可以在这个山上建房子,你有一台挖掘机,每天可以挖一座山一米,问你需要花多少代价可以分别盖1.2.3--座房子.(给出山的数量,以及每座山的高度) ...

随机推荐

  1. 哪些年,我们玩过的Git

    作者:玩世不恭的Coder公众号:玩世不恭的Coder时间:2020-06-05说明:本文为原创文章,未经允许不可转载,转载前请联系作者 哪些年,我们玩过的Git 前言一.前期工作常用基本概念的理解G ...

  2. DML_Data Modification_INSERT

    Data Modification (INSERT.DELETE.UPDATE.MERGE)之INSERT(基础知识,算是20年来第2次学习MSSQL吧,2005年折腾过一段时间的Oracle)INS ...

  3. cb48a_c++_STL_算法_重排和分区random_shuffle_stable_partition

    cb48a_c++_STL_算法_重排和分区random_shuffle_stable_partition random_shuffle()//重排,随机重排,打乱顺序 partition()分区,把 ...

  4. 认证授权方案之JwtBearer认证

    1.前言 回顾:认证方案之初步认识JWT 在现代Web应用程序中,即分为前端与后端两大部分.当前前后端的趋势日益剧增,前端设备(手机.平板.电脑.及其他设备)层出不穷.因此,为了方便满足前端设备与后端 ...

  5. <react> 组件的详细介绍:

    <react> 组件的详细介绍: 思维导图: 代码介绍: TodoList:(组件) import React, { Component } from 'react' import Sty ...

  6. docker配置国内镜像地址,解决无法pull镜像问题docker: Error response from daemon

    问题: 执行命令 $ docker run -it --rm -p 8888:8080 tomcat:8.5.32 报错 Unable to find image 'tomcat:8.5.32' lo ...

  7. SpringCloud教程第2篇:Ribbon(F版本)

    一.ribbon简介 Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign.在这一篇文章首先讲解下基于ribbon+rest. ribbon是一 ...

  8. shell 脚本操作informix数据库

    shell 脚本操作informix数据库的简单模板: functionName(){ dbaccess << ! database 库名; sql语句; ! } 栗子1:更新数据 fun ...

  9. spring框架中JDK和CGLIB动态代理区别

    转载:https://blog.csdn.net/yhl_jxy/article/details/80635012 前言JDK动态代理实现原理(jdk8):https://blog.csdn.net/ ...

  10. Python3-gevent模块-单线程下的"并发"-协程

    博客转载 http://www.cnblogs.com/alex3714/articles/5248247.html http://www.cnblogs.com/tkqasn/p/5705338.h ...