【线型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--座房子.(给出山的数量,以及每座山的高度) ...
随机推荐
- 时间序列神器之争:prophet VS lstm
一.需求背景 我们福禄网络致力于为广大用户提供智能化充值服务,包括各类通信充值卡(比如移动.联通.电信的话费及流量充值).游戏类充值卡(比如王者荣耀.吃鸡类点券.AppleStore充值.Q币.斗鱼币 ...
- DedeCms 标签中channelartlist设置属性标签样式的方法
实现的效果如下: {dede:channelartlist typeid='6' row='3' currentstyle='current'} <li class='{dede:field.c ...
- 并行处理框架Celery的Web监控管理服务-Flower
安装和使用 使用pip安装Flower: $ pip install flower或 pip install flower -U -i https://pypi.tuna.tsinghua.edu.c ...
- Spring boot添加配置类@Configuration并初始化@Bean,@Resource和@Autowired都为null
大写加黑,找了好久@Resource和@Autowired都依赖不到创建的bean的原因:@Bean的方法名即是创建的Bean名称 import org.activiti.engine.Process ...
- 解决:gradle 前言中不允许有内容
将Android Studio 升级到4.0然后创建一个新项目,编译出现“ gradle 前言中不允许有内容” 的错误,在网上找了很多资料,众说纷纭,但都没有解决我的问题,最后反复摸索把问题解决了. ...
- Linux防火墙iptables详解
iptables详解(思维导图) 1. 概述 1.1 iptable简介 1.2 防火墙的种类 1.3 netfilter 2. iptables的工作流程 2.1 iptables工作图示 2.2 ...
- Django自定义500的错误显示信息
这个方法应该对Django version 2.2.4以后的版本都有效,因为我的项目是这个版本,其他版本我并没有测试. 首先找到Django的exception.py文件路径: C:\python_ ...
- C语言中main函数的参数argc和argv
参考资料: http://wiki.opencv.org.cn/index.php/Main%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0argc%EF%BC%8Cargv% ...
- Activity学习笔记1
Activity概述 简单的理解Activity就是指Android手机或平板的一个屏,类似Window的一个窗口,浏览器的一个页面. Activity的4种状态 Activity的生命周期 创建Ac ...
- JavaSE基础之数组
数组 一.静态初始化 格式一 数据类型[] 变量名 = {元素1,元素2,元素3...}; 格式二 数据类型[] 变量名 = new 数据类型{元素1,元素2,元素3...}; 或者: 数据类型[] ...