「 COGS 2240 」 X 「 Luogu P2885 」 架设电话线
解题思路
首先很容易就想到了一个二维的朴素的 $dp$。
设 $dp[i][j]$ 表示第 $i$ 个位置的电话线杆的高度为 $j$ 时的最小花费,就需要枚举第 $i$ 个电话线杆、第 $i$ 个电话线杆的高度 $j$、第 $i-1$ 个电话线杆的高度 $k$。
状态转移方程如下
$$dp[i][j] = \min \{dp[i-1][k]+|j-k|\times c + (j-h[i])^2\}$$
但是这样的 $dp$ 过不了这题的数据范围。这个 $dp$ 的时间复杂度是 $\text{O}(n\times h^2)$。
所以需要考虑别的方法进行优化。
我们试着只枚举一个 $j$,而不是枚举 $j$ 和 $k$。
首先来说这个 $j$,它既是我们枚举的第 $i$ 个电话线杆的高度也是我们枚举的第 $i-1$ 根电话线杆的高度。$i-1$ 要相对 $i$ 产生影响,那么 $j$ 一定是大于 $h[i-1]$ 的。
我们在 $j\ge h[i-1]$ 时取一个最小值,同时又要消去绝对值的影响。这就要看 $j$ 的枚举顺序了。如果是正序枚举那么之后的j一定会大于当前的j,之后的 $j-$ 现在的 $j$,是正的。
所以现将现在的 $j\times c$ 减掉。到时候进行扩展的时候在将那时的 $j\times c$ 加上。就等价于加上了绝对值。倒序枚举只是换了下顺序,道理还是一样的就不再过多的解释。
再来看 $j\ge h[i]$ 的时候,这时的高度为 $j$ 的第 $i$ 根电话线杆已经能够被更新了。所以就将其更新。
然后再做一遍倒序枚举因为还要考虑 $i-1$ 比 $i$ 高的情况。
附上代码
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
inline int read() {
int x = , f = ; char c = getchar();
while (c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while (c <= '' && c >= '') {x = x* + c-''; c = getchar();}
return x * f;
}
const int maxn = 1e5+, INF = 1e9;
int n, c, h[maxn], f[maxn][], Ans = INF;
int main() {
freopen("phonewire.in", "r", stdin);
freopen("phonewire.out", "w", stdout);
n = read(), c = read();
for(int i=; i<=n; i++)
for(int j=; j<=; j++)
f[i][j] = INF;
for(int i=; i<=n; i++)
h[i] = read();
for(int i=h[]; i<=; i++) f[][i] = (i-h[]) * (i-h[]);
int minn;
for(int i=; i<=n; i++) {
minn = INF;
for(int j=; j<=; j++) {
if(j >= h[i-]) minn = min(minn, f[i-][j] - c*j);
if(j >= h[i]) f[i][j] = min(f[i][j], minn + c*j + (j-h[i]) * (j-h[i]));
}
minn = INF;
for(int j=; j>=; j--) {
if(j >= h[i-]) minn = min(minn, f[i-][j] + c*j);
if(j >= h[i]) f[i][j] = min(f[i][j], minn - c*j + (j-h[i]) * (j-h[i]));
}
}
for(int i=; i<=; i++) Ans = min(Ans, f[n][i]);
printf("%d", Ans);
fclose(stdin);
fclose(stdout);
return ;
}
「 COGS 2240 」 X 「 Luogu P2885 」 架设电话线的更多相关文章
- Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算)
Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算) Description T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放 ...
- Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流)
Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流) Description 问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同 ...
- Git 执行 「fork 出来的仓库」和「最新版本的原仓库」内容同步更新
当我们在 GitHub 上 fork 出一个仓库后,如果原仓库更新了,此时怎样才能保证我们 fork 出来的仓库和原仓库内容一致呢?我们一般关注的是仓库的 master(主干分支)的内容,通过以下步骤 ...
- FileUpload控件「批次上传 / 多档案同时上传」的范例--以「流水号」产生「变量名称」
原文出處 http://www.dotblogs.com.tw/mis2000lab/archive/2013/08/19/multiple_fileupload_asp_net_20130819. ...
- Java的参数传递是「值传递」还是「引用传递」?
关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题. 有人说Java中只有值传递,也有人说值传递和引用传递都是存在的,比较容易让人产生疑问. 关于值传递和引用传递其实需要分情况看待. ...
- Linux 小知识翻译 - 「Unix」和「兼容Unix的OS」
经常有人会问「Linux和Unix有什么区别?」,「Linux就是Unix吗?」. 回答一般都是「Linux是仿照Unix而开发的OS」,「Linux和Unix相似但不是一种OS」之类的. 关于「Li ...
- Linux 小知识翻译 - 「Linux」和「发行版」之间的关系
「Linux」本来指的仅仅是内核.5年之前大多都是这么认为的,但是最近不这么说了. 最近一般都说「Linux」是个 OS,这里的OS,不仅仅是内核,而是指电脑的整体环境(除了内核,还包括一些外围的软件 ...
- Java的参数传递是「按值传递」还是「按引用传递」?
JAVA传递的只有值,.传递的都是栈里的的值,只是有些栈里面的是值.有的是内存地址.(原文传递的都是栈里的的值有误,局部变量在栈中,成员变量在堆中,类变量(静态变量和常量)在方法区中,可以看做本文的变 ...
- 【微信小程序】开发实战 之 「配置项」与「逻辑层」
微信小程序作为微信生态重要的一环,在实际生活.工作.商业中的应用越来越广泛.想学习微信小程序开发的朋友也越来越多,本文将在小程序框架的基础上就微信小程序项目开发所必需的基础知识及语法特点进行了详细总结 ...
随机推荐
- luogu 4427 求和
bjoi 2018 求和 唯一一道可能切的题一个数组还没开long long就成0分了 题目大意: 一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的k次方和,而且每次的k可能是不同的 此处 ...
- 让你彻底明白JAVA中堆与栈的区别
原文地址:http://www.2cto.com/kf/201302/190704.html 简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象 ...
- openstack dnsmasq
killall dnsmasq systemctl restart openstack-nova-compute /sbin/dnsmasq --conf-file=/var/lib/libvirt/ ...
- fck 属性配置大全
优化FCKeditor文件夹和文件: 下载FCKeditor并解压之后,会产生_samples和 editor两个文件夹和几个文件,全部删除以_开头的文件夹和文件,因为这些都是FCKeditor的一些 ...
- bzoj 2442: [Usaco2011 Open]修剪草坪【单调栈】
设f[i]为i不选的最小损失,转移是f[i]=f[j]+e[i[(i-j-1<=k) 因为f是单调不降的,所以f[j]显然越靠右越好因为i-j-1<=k的限制,所以单调栈需要弹栈 #inc ...
- Liunx中虚拟机远程复制文件SCP命令
1.首先在虚拟机中新建 CentOSA .CentOSB 从远处复制文件到本地目录 scp -r root@192.168.1.24:/root/aa ./ 从CentosB虚拟机器上的/root/a ...
- Spring boot 分环境部署
一.如果配置文件为:application.properties时 1.application.properties用于填些公共文件 以下为不同环境的配置文件需要单独配置 application-de ...
- linux学习之路3 文件系统结构
一些有用的定义: linux文件系统为一个倒转的单根树状结构 文件系统的根为"/" linux系统文件严格区分大小写,而windows系统不区分大小写 路径使用"/&qu ...
- sql删除表中重复记录只保留一条记录
最终代码 update T_Fee set gzl_dfg_op = 'delete' where MetReadRecordID in ( select MetReadRecordID from T ...
- 【JAVA 学习笔记2】if使用例子
int a =3; if (a%2==0) { System.out.println(a+" 是偶数"); System.out.println(a+" 不是奇数&quo ...