题目:

https://www.luogu.org/problemnew/show/P2885

由于把每一根电线杆增加多少高度不确定,所以很难直接通过某种方法算出答案,考虑动态规划。

状态:f [ i ] [ j ]表示当第i根电线杆的高度为j时的最小代价和

转移:当前电线杆的高度只会影响它下一个电线杆的高度,所以就是用前一维的答案来更新后一维。在计算第i根电线杆和第i-1根电线杆时需要计算三部分答案:1.将第i根电线杆增加到j高度的代价 ( j - h [ i ])*(j - h [ i ] )。2.到第i-1根电线杆时的最小花费f [ i-1 ] [ k ](由于我们并不知道第i-1根电线杆的高度,所以需要枚举第i-1根电线杆的高度k)3. 第i根电线杆到第i-1根电线杆之间电线的代价( j - k )*C

由此我们得到转移方程:f [ i ] [ j ] = ( j - h [ i ] )^2 + min( f [ i - 1 ] [ k ] + | j - k |*C )

然而这需要我们用三重循环枚举,时间复杂度是O( n*C*C ),会超时(好像有人用这个卡过了。。。)。

优化:

我们把绝对值拆开来可以得到一个分段函数:

f [ i ] [ j ] = ( j - h [ i ] )^2 + min( f [ i - 1 ] [ k ] + j * C - k * C)  ,j>=k

f [ i ] [ j ] = ( j - h [ i ] )^2 + min( f [ i - 1 ] [ k ] + k * C - j * C )  ,j < k

我们把 j * C从min中提出来,就变成了:

f [ i ] [ j ] = ( j - h [ i ] )^2 + j * C + min( f [ i - 1 ] [ k ] - k * C)  ,j>=k

f [ i ] [ j ] = ( j - h [ i ] )^2 - j * C + min( f [ i - 1 ] [ k ] + k * C )  ,j < k

我们可以发现,min里面的东西只与k和i有关而与j无关,所以我们可以在外层枚举i,在内层预处理出f [ i - 1 ] [ k ] - k * C的前缀最小值和f [ i - 1 ] [ k ] + k * C的后缀最小值,然后再枚举j,这是就可以直接O(1)调用min(...)了。

同时由于每一维的状态只与上一维有关且不需要记录答案,所以可以通过滚动数组来将空间复杂度进一步优化到O(C)。

代码:(注意赋初值等细节)

 #include<bits/stdc++.h>
using namespace std;
int read()
{
int ans=;
char ch=getchar(),last=' ';
while(ch<''||ch>'')
{last=ch;ch=getchar();}
while(ch>=''&&ch<='')
{ans=ans*+ch-'';ch=getchar();}
if(last=='-')ans=-ans;
return ans;
}
const int M=1e5+,inf=1e9+;
int n,C,h[M],f[M][],m;
//f[i][j]表示第i根电线杆的高度为j时的最小代价和
int l[],r[];
int main()
{
n=read();C=read();
memset(f,0x3f,sizeof(f));
for(int i=;i<=n;i++)
h[i]=read(),m=max(m,h[i]);
for(int i=h[];i<=m;i++)
f[][i]=(i-h[])*(i-h[]);
for(int i=;i<=n;i++)
{
l[h[i-]-]=inf;
r[m+]=inf;
for(int k=h[i-];k<=m;k++)
l[k]=min(l[k-],f[i-][k]-k*C);
for(int k=m;k>=h[i];k--)
r[k]=min(r[k+],f[i-][k]+k*C);
for(int j=h[i-];j<=m;j++)
if(j>=h[i])f[i][j]=l[j]+(j-h[i])*(j-h[i])+C*j;
for(int j=m;j>=h[i];j--)
f[i][j]=min(f[i][j],r[j]-C*j+(j-h[i])*(j-h[i]));
}
int ans=inf;
for(int i=h[n];i<=m;i++)
ans=min(ans,f[n][i]);
printf("%d\n",ans);
return ;
}

P2885 [USACO07NOV]电话线Telephone Wire——Chemist的更多相关文章

  1. P2885 [USACO07NOV]电话线Telephone Wire

    P2885 [USACO07NOV]电话线Telephone Wire 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话 ...

  2. [USACO07NOV]电话线Telephone Wire

    [USACO07NOV]电话线Telephone Wire 时间限制: 1 Sec  内存限制: 128 MB 题目描述 电信公司要更换某个城市的网线.新网线架设在原有的 N(2 <= N &l ...

  3. [luoguP2885] [USACO07NOV]电话线Telephone Wire(DP + 贪心)

    传送门 真是诡异. 首先 O(n * 100 * 100) 三重循环 f[i][j] 表示到第 i 个柱子,高度是 j 的最小花费 f[i][j] = min(f[i - 1][k] + abs(k ...

  4. 【USACO07NOV】电话线Telephone Wire

    题目描述 电信公司要更换某个城市的网线.新网线架设在原有的 N(2 <= N <= 100,000)根电线杆上, 第 i 根电线杆的高度为 height_i 米(1 <= heigh ...

  5. [USACO 07NOV]电话线Telephone Wire

    题目描述 Farmer John's cows are getting restless about their poor telephone service; they want FJ to rep ...

  6. DP+滚动数组 || [Usaco2007 Nov]Telephone Wire 架设电话线 || BZOJ 1705 || Luogu P2885

    本来是懒得写题解的…想想还是要勤发题解和学习笔记…然后就滚过来写题解了. 题面:[USACO07NOV]电话线Telephone Wire 题解: F[ i ][ j ] 表示前 i 根电线杆,第 i ...

  7. 【动态规划】bzoj1705: [Usaco2007 Nov]Telephone Wire 架设电话线

    可能是一类dp的通用优化 Description 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线. 新的电话线架设 ...

  8. BZOJ_1705_[Usaco2007 Nov]Telephone Wire 架设电话线_DP

    BZOJ_1705_[Usaco2007 Nov]Telephone Wire 架设电话线_DP Description 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是 ...

  9. bzoj1705[Usaco2007 Nov]Telephone Wire 架设电话线(dp优化)

    1705: [Usaco2007 Nov]Telephone Wire 架设电话线 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 441  Solved: ...

随机推荐

  1. navicat 无法连接到腾讯云Mysql

    远程连接进入服务器 远程连接进入服务器之后,输入命令mysql -u root -p 之后输入mysql密码,进入mysql 命令环境 设置开启远程登录 GRANT ALL PRIVILEGES ON ...

  2. 【转载】Unix设计哲学 & 回车换行八卦 & EOF八卦 & UNIX目录结构八卦

    昨天看了这篇文章 <关于Unix哲学> 首先用了两个例子,用风扇吹出空肥皂盒 和 太空铅笔,来说明简单设计也能派上作用吧. Unix哲学,Wikipedia上列出了好几个版本,不同的人有不 ...

  3. JSP中过滤器的设置

    JSP中过滤器的设置 package com.filter; import java.io.IOException; import java.net.URLDecoder; import java.u ...

  4. 改动Android启动画面

    一.Android的启动步骤 1.启动Linux 2.载入Android 3.显示Android桌面 二.分析 Android载入开机动画的源代码文件是: /opt/android4.3/framew ...

  5. leetcode ----Trie/stack专题

    一:Implement Trie (Prefix Tree) 题目: Implement a trie with insert, search, and startsWith methods. Not ...

  6. string 是值类型,还是引用类型(.net)[转]

    转自http://hi.baidu.com/newfzks/item/b805f0f4edb0810dd89e7290 string 是值类型,还是引用类型(.net) 一. string 类型的用法 ...

  7. 访问某类型的元数据的方式-TypeDescriptor 类

    .NET Framework 提供了两种访问某类型的元数据的方式:通过 System.Reflection 命名空间中提供的反射 API,以及通过 TypeDescriptor 类.反射是可用于所有类 ...

  8. IDEA 使用方法快捷键

    Ctrl+Shift + Enter,语句完成“!”,否定完成,输入表达式时按 “!”键Ctrl+E,最近的文件Ctrl+Shift+E,最近更改的文件Shift+Click,可以关闭文件Ctrl+[ ...

  9. 调参侠的末日? Auto-Keras 自动搜索深度学习模型的网络架构和超参数

    Auto-Keras 是一个开源的自动机器学习库.Auto-Keras 的终极目标是允许所有领域的只需要很少的数据科学或者机器学习背景的专家都可以很容易的使用深度学习.Auto-Keras 提供了一系 ...

  10. Django值聚合,分组,事物,cookie,session

    1,聚合(aggregate):是queryset的一个 终止语句,它返回一个包含键值对的字典,键是的名称是聚合值的标识符,值是计算出来的聚合值,键的名称是按照字段和聚合函数自动生成出来的.用到的内置 ...