解题思路

首先很容易就想到了一个二维的朴素的 $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$ 高的情况。

附上代码

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. using namespace std;
  5. inline int read() {
  6. int x = , f = ; char c = getchar();
  7. while (c < '' || c > '') {if(c == '-') f = -; c = getchar();}
  8. while (c <= '' && c >= '') {x = x* + c-''; c = getchar();}
  9. return x * f;
  10. }
  11. const int maxn = 1e5+, INF = 1e9;
  12. int n, c, h[maxn], f[maxn][], Ans = INF;
  13. int main() {
  14. freopen("phonewire.in", "r", stdin);
  15. freopen("phonewire.out", "w", stdout);
  16. n = read(), c = read();
  17. for(int i=; i<=n; i++)
  18. for(int j=; j<=; j++)
  19. f[i][j] = INF;
  20. for(int i=; i<=n; i++)
  21. h[i] = read();
  22. for(int i=h[]; i<=; i++) f[][i] = (i-h[]) * (i-h[]);
  23. int minn;
  24. for(int i=; i<=n; i++) {
  25. minn = INF;
  26. for(int j=; j<=; j++) {
  27. if(j >= h[i-]) minn = min(minn, f[i-][j] - c*j);
  28. if(j >= h[i]) f[i][j] = min(f[i][j], minn + c*j + (j-h[i]) * (j-h[i]));
  29. }
  30. minn = INF;
  31. for(int j=; j>=; j--) {
  32. if(j >= h[i-]) minn = min(minn, f[i-][j] + c*j);
  33. if(j >= h[i]) f[i][j] = min(f[i][j], minn - c*j + (j-h[i]) * (j-h[i]));
  34. }
  35. }
  36. for(int i=; i<=; i++) Ans = min(Ans, f[n][i]);
  37. printf("%d", Ans);
  38. fclose(stdin);
  39. fclose(stdout);
  40. return ;
  41. }

「 COGS 2240 」 X 「 Luogu P2885 」 架设电话线的更多相关文章

  1. Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算)

    Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算) Description T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放 ...

  2. Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流)

    Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流) Description 问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同 ...

  3. Git 执行 「fork 出来的仓库」和「最新版本的原仓库」内容同步更新

    当我们在 GitHub 上 fork 出一个仓库后,如果原仓库更新了,此时怎样才能保证我们 fork 出来的仓库和原仓库内容一致呢?我们一般关注的是仓库的 master(主干分支)的内容,通过以下步骤 ...

  4. FileUpload控件「批次上传 / 多档案同时上传」的范例--以「流水号」产生「变量名称」

    原文出處  http://www.dotblogs.com.tw/mis2000lab/archive/2013/08/19/multiple_fileupload_asp_net_20130819. ...

  5. Java的参数传递是「值传递」还是「引用传递」?

    关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题. 有人说Java中只有值传递,也有人说值传递和引用传递都是存在的,比较容易让人产生疑问. 关于值传递和引用传递其实需要分情况看待. ...

  6. Linux 小知识翻译 - 「Unix」和「兼容Unix的OS」

    经常有人会问「Linux和Unix有什么区别?」,「Linux就是Unix吗?」. 回答一般都是「Linux是仿照Unix而开发的OS」,「Linux和Unix相似但不是一种OS」之类的. 关于「Li ...

  7. Linux 小知识翻译 - 「Linux」和「发行版」之间的关系

    「Linux」本来指的仅仅是内核.5年之前大多都是这么认为的,但是最近不这么说了. 最近一般都说「Linux」是个 OS,这里的OS,不仅仅是内核,而是指电脑的整体环境(除了内核,还包括一些外围的软件 ...

  8. Java的参数传递是「按值传递」还是「按引用传递」?

    JAVA传递的只有值,.传递的都是栈里的的值,只是有些栈里面的是值.有的是内存地址.(原文传递的都是栈里的的值有误,局部变量在栈中,成员变量在堆中,类变量(静态变量和常量)在方法区中,可以看做本文的变 ...

  9. 【微信小程序】开发实战 之 「配置项」与「逻辑层」

    微信小程序作为微信生态重要的一环,在实际生活.工作.商业中的应用越来越广泛.想学习微信小程序开发的朋友也越来越多,本文将在小程序框架的基础上就微信小程序项目开发所必需的基础知识及语法特点进行了详细总结 ...

随机推荐

  1. train_action

    # 导入数值计算模块 import numpy as np import tensorflow as tf # 创建计算会话 sess = tf.Session() # 生成数据,创建占位符和变量A ...

  2. 二分lower_bound()与upper_bound()的运用

    <span style="color:#6633ff;">/* G - 二分 Time Limit:2000MS Memory Limit:32768KB 64bit ...

  3. ios25---图片拉伸

    控制器: // // ViewController.m // 12-图片的拉伸问题 // // Created by xiaomage on 15/12/30. // Copyright © 2015 ...

  4. Linux/Android——Input系统之frameworks层InputManagerService (六)【转】

    本文转载自:http://blog.csdn.net/u013491946/article/details/72638954 版权声明:免责声明: 本人在此发文(包括但不限于汉字.拼音.拉丁字母)均为 ...

  5. hive时间

    Hive中日期函数总结:1.时间戳函数日期转时间戳:从1970-01-01 00:00:00 UTC到指定时间的秒数select unix_timestamp(); --获得当前时区的UNIX时间戳s ...

  6. [ZJOI 2007] 矩阵游戏

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1059 [算法] 二分图最大匹配 时间复杂度 : O(N^3) [代码] #inclu ...

  7. Tool:Adobe Photoshop

    ylbtech-Tool-Adobe:Adobe Photoshop 1.返回顶部 1. Adobe Photoshop,简称“PS”,是由Adobe Systems开发和发行的图像处理软件. Pho ...

  8. 使用inet_ntoa() 时编译提示错误:

    char*inet_ntoa(struct in_addr in)将一个IP转换成一个互联网标准点分格式的字符串. 我把 inet_ntoa 需要的头文件加上去:    #include <sy ...

  9. mysql5.7 1055

    错误提示: [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggreg ...

  10. [C++ STL] 常用算法总结

    1 概述 STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包含头文件<alg ...