[POJ3612] Telephone Wire(暴力dp+剪枝)

题面

有N根电线杆,初始高度为h[i],要给相邻的两根连线。可以选择拔高其中一部分电线杆,把一根电线杆拔高\(\Delta H\)的代价为\(\Delta H^2\)。拔高后,要给相邻的电线杆连线,连线相邻两根电线杆操作的代价为\(C\Delta H\),其中C是一个常量且已经给出。求最小总代价。

分析

考虑一个显然的dp,设\(dp[i][j]\)表示前i根电线杆,第i根拔到高度j的最小代价,记H表示max(h[i])

则\(dp[i][j]=min(dp[i][j],dp[i-1][k]+C \times |j-k|+(j-h[i])^2),k \in [h[i-1],H)\) 。这里k的意义是第i-1根电线杆的高度

直接转移是\(O(nH^2)\)的,但有一个很强的剪枝可以通过本题

若我们固定i,j,考虑k对\(dp[i-1][k]+C \times |j-k|+(j-h[i])^2\)的影响,k对\(dp[i-1][k]\)造成了\((k-h[i-1])^2\)的影响,又造成了\(C \times |j-k|\)的影响,总的影响应该是一个关于k的二次函数。而我们知道二次函数是有对称性和单调性的。我们从小到大枚举k,若\(dp[i-1][k]+C \times |j-k|+(j-h[i])^2>dp[i][j]\),说明k已经大于那个二次函数的对称轴了,之后的函数值只会更大,这个时候就可以停止枚举k

代码

//暴力出奇迹
#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f3f
#define rg register
#define maxn 100000
#define maxh 100
using namespace std;
typedef long long ll;
inline void qread(int &x){
x=0;
int sign=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') sign=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
x=x*sign;
} int n,c,lim;
int h[maxn+5];
int dp[maxn+5][maxh+5];
inline int abs(int x){
return x>=0?x:-x;
}
inline int min(int x,int y){
return x<=y?x:y;
}
int main(){
qread(n);
qread(c);
lim=0;
for(rg int i=1;i<=n;i++){
qread(h[i]);
lim=max(lim,h[i]);
}
memset(dp,0x3f,sizeof(dp));
for(rg int j=h[1];j<=lim;j++){
dp[1][j]=(j-h[1])*(j-h[1]);
}
for(rg int i=2;i<=n;i++){
for(rg int j=h[i];j<=lim;j++){//注意不用从0开始
int last=INF;
for(rg int k=h[i-1];k<=lim;k++){
int now=dp[i-1][k]+c*abs(j-k)+(j-h[i])*(j-h[i]);
if(dp[i][j]>now) dp[i][j]=now;
if(now>last) break;//由于代价是二次函数,找到最小值点就不用再找了
//这是很强的一个优化
last=now;
}
}
}
int ans=INF;
for(rg int i=h[n];i<=lim;i++) ans=min(ans,dp[n][i]);
printf("%d\n",ans);
}

[POJ3612] Telephone Wire(暴力dp+剪枝)的更多相关文章

  1. POJ3612:Telephone Wire

    传送门 一道很棒的DP题目. 裸的DP方程很好搞: $f[i][j]=min \{ f[i-1][k]+ C \times |k-j| +(k-a[i])^2 \}$ 这个复杂度显然无法承受,考虑优化 ...

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

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

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

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

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

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

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

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

  6. [USACO07NOV]电话线Telephone Wire

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

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

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

  8. P2885 [USACO07NOV]电话线Telephone Wire

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

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

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

随机推荐

  1. mysql语句之DDL

    SQL分类: DDL(Data Definition Languages)语句:数据定义语言,这些语句定义了不同的数据段.数据库.表.列.索引等数据库对象的定义.常用的语句关键字主要包括create. ...

  2. css炫酷动画收藏

    1.按钮.hover.input动画(cssfx) https://cssfx.dev/ 2.svg 矢量定制icon(ikonate) https://www.ikonate.com/#conten ...

  3. linux手动测试 rsync 的同步情况

    特别强调:此步很关键,如果这不能同步,后面的 inotify 配好了也不会同步数据. 1) 分别创建待同步数据 [root@rsync-client-inotify ~]# mkdir /data/{ ...

  4. Power Designer将数据库表结构导出到Word

     一.   安装与运行PowerDesigner(本例中用的版本是15.1) 二.“File”→“New Model”→“Categories”→“Information”→“Physical Dat ...

  5. ubuntu14彻底删除mysql!!!(精)

    解决方法: 删除mysql前 先删除一下 /var/lib/mysql 还有 /etc/mysql sudo rm /var/lib/mysql/ -R sudo rm /etc/mysql/ -R ...

  6. xml与json互转

    依赖包: <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib< ...

  7. 获取kingeditor编辑器内容

    //初始化编辑器 var editorMini = KindEditor.create('.editor-mini',{ width : '70%', height : '250px', resize ...

  8. python-列表元祖字典集合

    列表 list = ["a", "b", "c", "d"]元祖 tup = (1, 2, 3, 4, 5 ) 1.元组 ...

  9. OC + RAC (五) RACMulticastConnection

    -(void)_test5{ //弊端:有几个订阅者就会请求几次数据 // 1.创建信号 RACSignal *signal = [RACSignal createSignal:^RACDisposa ...

  10. Primary Key Increase by Trigger

    Oracle Create Table: CREATE TABLE TAB( ID NUMBER(10) NOT NULL PRIMARY KEY, NAME VARCHAR(19) NOT NULL ...