【线型DP】CF1012C Hills 小山坡
来了来了。
题目:
给你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
5
1 1 1 1 1
1 2 2
3
1 2 3
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 小山坡的更多相关文章
- 【线型DP】洛谷P2066 机器分配
[线型DP]洛谷P2066 机器分配 标签(空格分隔): 线型DP [题目] 题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配 ...
- CF1012C Hills 题解【DP】
思路还是比较简单的 dp 吧,但是就是想不出来-甚至类似的方程都被自己推翻了 Description Welcome to Innopolis city. Throughout the whole y ...
- [bzoj3209][花神的数论题] (数位dp+费马小定理)
Description 背景众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦.描述话说花神这天又来讲课了.课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了. ...
- 洛谷 CF1012C Hills (动态规划)
题目大意:有n个山丘 , 可以在山丘上建房子 , 建房子的要求是 : 该山丘的左右山丘严格的矮于该山丘 (如果有的话),你有一架挖掘机,每单位时间可以给一个山丘挖一个单位的高度,问你想要建造 1,2, ...
- 【线型DP模板】最上上升子序列(LIS),最长公共子序列(LCS),最长公共上升子序列(LCIS)
BEGIN LIS: 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序 ...
- 【线型DP】【LCS】UVA_10635 Prince and Princess
嘤嘤嘤,我又来了,刚A完就写,这个沙雕题有丶恶心. ???时间4.11发现所有表情包都莫得了 题目: In an n×n chessboard, Prince and ...
- CF1012C Hills
显然的DP是,dp[i][j][val] val是1e6的 简化 发现,其实决策很有限,最优解的i-1的val选择有限 题解 这里的一个trick是,f[i][j][0]转移不考虑a[i]和a[i-1 ...
- 线性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[ ...
- 洛谷 CF1012C Hills(动态规划)
题目大意: 有几座山,如果一座山左右两边的山比它矮,那么可以在这个山上建房子,你有一台挖掘机,每天可以挖一座山一米,问你需要花多少代价可以分别盖1.2.3--座房子.(给出山的数量,以及每座山的高度) ...
随机推荐
- java代码(4)---guava之Immutable(不可变)集合
Immutable(不可变)集合 一,概述 guava是google的一个库,弥补了java语音的很多方面的不足,很多在java8中已有实现,暂时不展开,Collections是jdk提供的一个工 ...
- “造轮运动”之 ORM框架系列(三)~ 干货呈上
这一趴里面,我就来正式介绍一下CoffeeSQL的干货. 首先要给CoffeeSQL来个定位:最开始就是由于本人想要了解ORM框架内部的原理,所以就四处搜寻有关的博客与学习资料,就是在那个夏天 ...
- 为什么zookeeper的节点配置的个数必须是奇数个
选举机制(FastLeaderElection算法):sid最大且被超过集群中超过半数的机器拥护就会成为leader.所以只有两种情况无法选出leader:整个集群只有2台服务器(注意不是只剩2台,而 ...
- Python简单http服务实现
1.代码实现 # -*- coding: utf-8 -*-"""Created on Tue Jun 11 18:12:01 2019 @author: wangymd ...
- C语言视频教程下载(百万年薪程序员录制,免费公开)
<C/C++语言高性能服务开发基础>您可以自由下载.传播.发布或其它商业用途. 视频文件共13.6G,提供了QQ群文件和百度网盘两种方法,建议采用QQ群文件下载,速度较快. 一.下载方法 ...
- 线性代数的28法则:作为程序员掌握这些API就够用了……
目录 1. 向量 & 矩阵 1.1. 问: np.ndarray 与 np.matrix 的区别 1.2. 向量空间 2. 算术运算 2.1. 为什么线性代数定义的乘积运算不按照加法的规则(按 ...
- [noi.ac省选模拟赛]第10场题解集合
题目 比赛界面. T1 不难想到,对于一个与\(k\)根棍子连接的轨道,我们可以将它拆分成\(k+1\)个点,表示这条轨道不同的\(k+1\)段. 那么,棍子就成为了点与点之间的边.可以发现,按照棍子 ...
- 如何解决在electron里无法使用puppeteer的evaluate函数
报错如图,只需要注释掉 index.html 含有 http-equiv="Content-Security-Policy 的 meta 标签就可以了.
- mitmproxy的简单使用
第1则 ---抓包工具mitmdump的使用--- 一.什么是抓包?怎么抓包? 1.抓包(packet capture)就是将网络传输发送与接收的数据包进行截获.重发.编辑.转存等操作,也用来检查网络 ...
- 求求你,别问了,Java字符串是不可变的
最近,又有好几个小伙伴问我这个问题:"二哥,为什么 Java 的 String 要设计成不可变的啊?"说实话,这也是一道非常经典的面试题,面试官超喜欢问.我之前写过这方面的文章,现 ...