Covered Walkway

Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1496    Accepted Submission(s): 602

Problem Description
Your university wants to build a new walkway, and they want at least part of it to be covered. There are certain points which must be covered. It doesn’t matter if other points along the walkway are covered or not. 
The building contractor has an interesting pricing scheme. To cover the walkway from a point at x to a point at y, they will charge c+(x-y)2, where c is a constant. Note that it is possible for x=y. If so, then the contractor would simply charge c
Given the points along the walkway and the constant c, what is the minimum cost to cover the walkway?
 
Input
There will be several test cases in the input. Each test case will begin with a line with two integers, n (1≤n≤1,000,000) and c (1≤c≤109), where n is the number of points which must be covered, and c is the contractor’s constant. Each of the following n lines will contain a single integer, representing a point along the walkway that must be covered. The points will be in order, from smallest to largest. All of the points will be in the range from 1 to 109, inclusive. The input will end with a line with two 0s.
 
Output
For each test case, output a single integer, representing the minimum cost to cover all of the specified points. Output each integer on its own line, with no spaces, and do not print any blank lines between answers. All possible inputs yield answers which will fit in a signed 64-bit integer.
 
Sample Input
10 5000
1
23
45
67
101
124
560
789
990
1019
0 0
 
Sample Output
30726
 
Source
 

题意:

有n个点需要被覆盖,覆盖第j到第i之间的点的花费是c+(x[i]-x[j])^2,问把所有的点都覆盖的最小花费。

输入n,c

输入n个点x[1...n]

当输入0 0时结束

代码:

//有状态转移方程dp[i]=min(dp[j]+C+(a[i]-a[j+1])*(a[i]-a[j+1])),数据是1e6的两重循环必然不行
//设k<j<i,当到达i点时如果从j点转移到i比从k点转移到i更优则有:dp[j]+C+(a[i]-a[j+1])^2<dp[k]+C+(a[i]-a[k+1])^2
//展开得:(dp[j]-dp[k]+a[j+1]^2-a[k+1]^2)/2*(a[j+1]-a[k+1])<a[i].其中a[i]常量(实现时是一重循环枚举i点),
//我们设yj=dp[j]+a[j+1]^2,xj=a[j+1] =>(yj-yk)/2*(xj-xk)<a[i].左边是计算斜率的式子。我们用一个单调队列
//来存储能够转移到i点状态的点并且队头是转移到i点状态的最优的解,每次要保持队头是最优解就要根据
//(yj-yk)/2*(xj-xk)<a[i]用队头去和队列中第二个去比较(如果队头不优于第二个就要删去队头元素)。
//设g[i,j]表示直线j-i的斜率,如果有g[k,j]>g[i,j]那么j点永远不可能是i的最优解,因为:
//我们假设g[i,j]<a[i],那么就是说i点要比j点优,排除j点。如果g[i,j]>=a[i],那么j点此时是比i点要更优,
//但是同时g[j,k]>g[i,j]>sum[i]。这说明还有k点会比j点更优,同样排除j点。排除多余的点,这便是一种优化!
//其实就是维护一个斜率递增的(下凸上凹)的图形。因此要把i点加入队列之前先判断是否能够维护斜率递增如果
//不能就把队列最后一个元素删掉直到是斜率递增的然后加入i点。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=;
int n,m,que[maxn];
ll dp[maxn],a[maxn];
ll getdp(int i,int j){
return dp[j]+m+(a[i]-a[j+])*(a[i]-a[j+]);
}
ll getup(int j,int k){
return dp[j]-dp[k]+a[j+]*a[j+]-a[k+]*a[k+];
}
ll getlow(int j,int k){
return *(a[j+]-a[k+]);
}
int main()
{
while(scanf("%d%d",&n,&m)&&(n+m)){
for(int i=;i<=n;i++) scanf("%lld",&a[i]);
int head=,tail=;
dp[]=;
que[tail++]=;
for(int i=;i<=n;i++){
while(head+<tail&&getup(que[head+],que[head])<=a[i]*getlow(que[head+],que[head]))
head++;
dp[i]=getdp(i,que[head]);
while(head+<tail&&getup(que[tail-],que[tail-])*getlow(i,que[tail-])>=getup(i,que[tail-])*getlow(que[tail-],que[tail-]))
tail--;
que[tail++]=i;
}
printf("%lld\n",dp[n]);
}
return ;
}

HDU 4258 斜率优化dp的更多相关文章

  1. hdu 3669(斜率优化DP)

    Cross the Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others) ...

  2. HDU 2829 斜率优化DP Lawrence

    题意:n个数之间放m个障碍,分隔成m+1段.对于每段两两数相乘再求和,然后把这m+1个值加起来,让这个值最小. 设: d(i, j)表示前i个数之间放j个炸弹能得到的最小值 sum(i)为前缀和,co ...

  3. hdu 3045 斜率优化DP

    思路:dp[i]=dp[j]+sum[i]-sum[j]-(i-j)*num[j+1]; 然后就是比较斜率. 注意的时这里j+t<=i: #include<iostream> #in ...

  4. Print Article HDU - 3507 -斜率优化DP

    思路 : 1,用一个单调队列来维护解集. 2,假设队列中从头到尾已经有元素a b c.那么当d要入队的时候,我们维护队列的下凸性质, 即如果g[d,c]<g[c,b],那么就将c点删除.直到找到 ...

  5. HDU 3507 斜率优化dp

    Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  6. HDU 3507斜率优化dp

    Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  7. HDU 3507 斜率优化 DP Print Article

    在kuangbin巨巨博客上学的. #include <iostream> #include <cstdio> #include <cstring> #includ ...

  8. HDU 2993 MAX Average Problem(斜率优化DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 题目大意:给定一个长度为n(最长为10^5)的正整数序列,求出连续的最短为k的子序列平均值的最大 ...

  9. hdu 2829 Lawrence(斜率优化DP)

    题目链接:hdu 2829 Lawrence 题意: 在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和. ...

随机推荐

  1. netty in action 笔记 二

    netty的数据容器 网络数据的基本单位大多为字节,Java NIO 提供了ByteBuffer 作为它的字节容器,但使用起来过于复杂和繁琐.在Netty中, ByteBuffer 替代品是ByteB ...

  2. FPGA学习-VGA接口

    一般FPGA开发板的VGA会向用户暴露两共五个种接口,第一种是时序信号,用于同步传输和显示:第二种是色彩信号,用于随着时序把色彩显示到显示器上 时序接口 行同步信号-用于指示一行内像素的显示 场同步信 ...

  3. POJ 2184 Cow Exhabition

    "Fat and docile, big and dumb, they look so stupid, they aren't much fun..." - Cows with G ...

  4. Python3 Tkinter-Button

    1.绑定事件处理函数 from tkinter import * def hello(): print('Hello!') root=Tk() button=Button(root,text='cli ...

  5. 学霸系统PipeLine功能规格说明书

    学霸系统PipeLine功能规格说明书共分为以下三部分: 1.产品面向用户群体 2.用户使用说明 3.产品功能具体实现 1.产品面向用户群体 我们这组的项目并不是传统意义上能发布并进行展示的项目,因此 ...

  6. java多线程三之线程协作与通信实例

    多线程的难点主要就是多线程通信协作这一块了,前面笔记二中提到了常见的同步方法,这里主要是进行实例学习了,今天总结了一下3个实例: 1.银行存款与提款多线程实现,使用Lock锁和条件Condition. ...

  7. ubuntu中下载sublime相关问题

    1.SublimeText3的安装 在网上搜索了一些ubuntu下关于sublime-text-3安装的方法,在这里针对自己尝试的情况进行反馈: 方法一(未成功): 在终端输入以下代码: sudo a ...

  8. lintcode-184-最大数

    184-最大数 给出一组非负整数,重新排列他们的顺序把他们组成一个最大的整数. 注意事项 最后的结果可能很大,所以我们返回一个字符串来代替这个整数. #### 样例 给出 [1, 20, 23, 4, ...

  9. TCP系列08—连接管理—7、TCP 常见选项(option)

    一.TCP选项概述 在前面介绍TCP头的时候,我们说过tcp基本头下面可以带有tcp选项,其中有些选项只能在连接过程中随着SYN包发送,有些可以延后.下表汇总了一些tcp选项 其中我标记为红色的部分是 ...

  10. QT分析之网络编程

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201002842553382/ 首先对Windows下的网络编程总结一下: 如果是服务器 ...