[USACO07NOV]电话线Telephone Wire

时间限制: 1 Sec  内存限制: 128 MB

题目描述

电信公司要更换某个城市的网线。新网线架设在原有的 N(2 <= N <= 100,000)根电线杆上, 第
i 根电线杆的高度为 height_i 米(1 <= height_i <= 100)。 网线总是从一根电线杆的顶端被引到
相邻的那根的顶端,如果这两根电线杆的高度不同,那么电信公司就必须为此支付 C*电线
杆高度差(1 <= C <= 100)的费用。电线杆不能移动, 只能在相邻电线杆间按原有的顺序架设
网线。加高某些电线杆能减少架设网线的总花费,但需要支付一定的费用,一根电线杆加高
X 米的费用是 X^2。 请你计算一下,如何合理地进行这两种工作,使网线改造工程的最小费
用。

输入

  • Line 1: Two space-separated integers: N and C

  • Lines 2..N+1: Line i+1 contains a single integer: heighti

输出

  • Line 1: The minimum total amount of money that it will cost Farmer John to attach the new telephone wire.

样例输入

5 2
2
3
5
1
4

样例输出

15
题解:
f[i][j]表示第i个电线杆高度为j时所需要的最少的费用。
然后很快就可以得出暴力代码,每次枚举上一个电线杆的高度就可以了。
先付上暴力代码:(TLE到爆表)
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
using namespace std;
long long n,m;
long long a[],f[][],mmax;
int main()
{
long long i,j,k;
scanf("%lld%lld",&n,&m);
memset(f,/,sizeof(f));
for(i=;i<=n;i++)
{
scanf("%lld",&a[i]);
mmax=max(mmax,a[i]);
}
for(i=a[];i<=mmax;i++)
{
int s=i-a[];
f[][i]=s*s;
}
for(i=;i<=n;i++)
{
for(j=a[i-];j<=mmax;j++)
{
for(k=a[i];k<=mmax;k++)
{
int s=k-a[i];
f[i][k]=min(f[i][k],s*s+f[i-][j]+m*abs(j-k));
}
}
}
long long ans=;
for(i=a[n];i<=mmax;i++)
ans=min(ans,f[n][i]);
cout<<ans;
return ;
}

显然是需要优化的,仔细想一想就可以看出,每次实际上只有两种情况:

1.i-1的高度比i低。

2.i-1的高度比i高。

第一种情况下f[i][j]的结果为f[i-1][min]+abs(j-min)*k+(j-a[i])^2显然是有最小值的,所以只要记录min就可以直接算出f[i][j]的值。

第二种情况下f[i][j]的结果为f[i-1][min]+abs(j-min)*k+(j-a[i])^2,但由于随着j的增加每次min的值都有可能会改变,所以需要用到一个单调队列来记录最小值。

以下为AC代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
using namespace std;
long long n,m;
long long a[],f[][],mmax;
int main()
{
long long i,j,k;
scanf("%lld%lld",&n,&m);
memset(f,,sizeof(f));
for(i=; i<=n; i++)
{
scanf("%lld",&a[i]);
mmax=max(mmax,a[i]);
}
for(i=a[]; i<=mmax; i++)
{
int s=i-a[];
f[][i]=s*s;
}
for(i=; i<=n; i++)
{
int p[],head=,tail=,mmin=;
for(j=a[i-];j<a[i];j++)
{
if(f[i-][j]+abs(a[i]-j)*m<f[i-][mmin]+abs(a[i]-mmin)*m||mmin==)
mmin=j;
}
int ssss=max(a[i],a[i-]);
p[++tail]=ssss;
for(j=ssss+;j<=mmax;j++)
{
while(f[i-][j]+abs(j-a[i])*m<f[i-][p[tail]]+abs(p[tail]-a[i])*m&&head<=tail)tail--;
p[++tail]=j;
}
for(j=a[i];j<=mmax;j++)
{
f[i][j]=min(f[i][j],f[i-][mmin]+abs(j-mmin)*m+(j-a[i])*(j-a[i]));
f[i][j]=min(f[i][j],f[i-][p[head]]+abs(j-p[head])*m+(j-a[i])*(j-a[i]));
if(f[i-][mmin]-abs(j-mmin)*m>f[i-][j])mmin=j;
if(p[head]==j)head++;
}
}
long long ans=1e18;
for(i=a[n]; i<=mmax; i++)
ans=min(ans,f[n][i]);
cout<<ans;
return ;
}

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

  1. P2885 [USACO07NOV]电话线Telephone Wire

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

  2. P2885 [USACO07NOV]电话线Telephone Wire——Chemist

    题目: https://www.luogu.org/problemnew/show/P2885 由于把每一根电线杆增加多少高度不确定,所以很难直接通过某种方法算出答案,考虑动态规划. 状态:f [ i ...

  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. 【动态规划】bzoj1705: [Usaco2007 Nov]Telephone Wire 架设电话线

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

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

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

  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. 【初识Python】

    一.Python的简介 1.什么是python? Python(发音:[ 'paiθ(ə)n; (US) 'paiθɔn ]),是一种面向对象的解释性的计算机程序设计语言,也是一种功能强大而完善的通用 ...

  2. 也许是目前实现最好的js模拟滚动插件

    finger-mover 是一个集成 Fingerd(移动端以手指为单位的事件管理方案) 和 Moved(微型运动方案) 为一体的移动端动效平台,finger-mover 本身并不能为你做什么,但是附 ...

  3. 基于spark和sparkstreaming的word2vec

    概述 Word2vec是一款由谷歌发布开源的自然语言处理算法,其目的是把words转换成vectors,从而可以用数学的方法来分析words之间的关系.Spark其该算法进行了封装,并在mllib中实 ...

  4. My-Blog搭建过程:如何让一个网站从零到可以上线访问

    文章简述 5月13号的时候,上线了自己的个人博客网站:http://blog.hanshuai.xin,随后在平台上发布了一篇关于My-Blog的介绍博客<Docker+SpringBoot+M ...

  5. repo版本切换

    repo init -u https://android.googlesource.com/platform/manifest repo sync 之后 这样初始化之后,相当于下载了全部的分支, 本想 ...

  6. 无锁模式的Vector

    这两天学习无锁的并发模式,发现相比于传统的 同步加锁相比,有两点好处1.无锁 模式 相比于 传统的 同步加锁  提高了性能 2.无锁模式 是天然的死锁免疫 下来介绍无锁的Vector--- LockF ...

  7. ES6核心内容精讲--快速实践ES6(一)

    前言 本文大量参考了阮一峰老师的开源教程ECMAScript6入门,适合新手入门或者对ES6常用知识点进行全面回顾,目标是以较少的篇幅涵盖ES6及部分ES7在实践中的绝大多数使用场景.更全面.更深入的 ...

  8. 11.Java 加解密技术系列之 总结

    Java 加解密技术系列之 总结 序 背景 分类 常用算法 原理 关于代码 结束语 序 上一篇文章中简单的介绍了第二种非对称加密算法 — — DH,这种算法也经常被叫做密钥交换协议,它主要是针对密钥的 ...

  9. laravel实现excel表格导出

    记得引用一下excel,现在laravel5.2都默认自带的,不需要自己再 Composer安装依赖了. use Excel; 然后方法里这样写 //$cellData自己要进行导出的数组 Array ...

  10. [netty源码分析]3 eventLoop 实现类SingleThreadEventLoop职责与实现

    eventLoop是基于事件系统机制,主要技术由线程池同队列组成,是由生产/消费者模型设计,那么先搞清楚谁是生产者,消费者内容 SingleThreadEventLoop 实现 public abst ...