HDU 4258 斜率优化dp
Covered Walkway
Time Limit: 30000/10000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1496 Accepted Submission(s): 602
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?
23
45
67
101
124
560
789
990
1019
题意:
有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的更多相关文章
- hdu 3669(斜率优化DP)
Cross the Wall Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 327680/327680 K (Java/Others) ...
- HDU 2829 斜率优化DP Lawrence
题意:n个数之间放m个障碍,分隔成m+1段.对于每段两两数相乘再求和,然后把这m+1个值加起来,让这个值最小. 设: d(i, j)表示前i个数之间放j个炸弹能得到的最小值 sum(i)为前缀和,co ...
- hdu 3045 斜率优化DP
思路:dp[i]=dp[j]+sum[i]-sum[j]-(i-j)*num[j+1]; 然后就是比较斜率. 注意的时这里j+t<=i: #include<iostream> #in ...
- Print Article HDU - 3507 -斜率优化DP
思路 : 1,用一个单调队列来维护解集. 2,假设队列中从头到尾已经有元素a b c.那么当d要入队的时候,我们维护队列的下凸性质, 即如果g[d,c]<g[c,b],那么就将c点删除.直到找到 ...
- HDU 3507 斜率优化dp
Print Article Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- HDU 3507斜率优化dp
Print Article Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- HDU 3507 斜率优化 DP Print Article
在kuangbin巨巨博客上学的. #include <iostream> #include <cstdio> #include <cstring> #includ ...
- HDU 2993 MAX Average Problem(斜率优化DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 题目大意:给定一个长度为n(最长为10^5)的正整数序列,求出连续的最短为k的子序列平均值的最大 ...
- hdu 2829 Lawrence(斜率优化DP)
题目链接:hdu 2829 Lawrence 题意: 在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和. ...
随机推荐
- C struct中的位域 bitfield
C struct中的位域 bitfield 结构体的成员可以限制其位域,每个成员可以使用用比字节还小的取值范围,下面的结构体s1中,四个成员每个成员都是2bit的值(0~3),整个结构体占据的空间依然 ...
- A Compatible Pair
Description “年”是一个生活在海洋深处的怪物.每年,它都出现在陆地上,吞噬牲畜甚至是人.为了让怪物离开,人们用红色,光线和爆炸的声音填满他们的村庄,所有这些都吓跑了怪物. 小汤米有 n ...
- MVC4 DropDownList (一) — 使用方法
1.下面代码包含了三种绑定DropDownList的方法 using System; using System.Collections.Generic; using System.Linq; usin ...
- 基于gulp的前端自动化开发构建新
关于gulp的使用,已经在之前写过一篇文章,但是遗留了一个问题.问题是实现文件的增量式更新,就是给html引入的js和css文件打上标记.每次更新标记更新. 上篇文章想通过开发同时实现标记的实时更新, ...
- HashMap源码剖析及实现原理分析(学习笔记)
一.需求 最近开发中,总是需要使用HashMap,而为了更好的开发以及理解HashMap:因此特定重新去看HashMap的源码并写下学习笔记,以便以后查阅. 二.HashMap的学习理解 1.我们首先 ...
- Ehcache概念篇
前言 缓存用于提供性能和减轻数据库负荷,本文在缓存概念的基础上对Ehcache进行叙述,经实践发现3.x版本高可用性不好实现,所以我采用2.x版本. Ehcache是开源.基于缓存标准.基于java的 ...
- Hibernate学习实现查询
- [C/C++] C/C++错题集
1. 解析: A:在GCC下输出:0 在VC6.0下输出:1 B:在GCC下输出:段错误 (核心已转储) 在VC6.0下输出:已停止工作,出现了一个问题,导致程序停止正常工作. C:正常 ...
- [剑指Offer] 58.对称的二叉树
题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. [思路]递归,关键是isSame函数中的最后一句 /* struct Tree ...
- [剑指Offer] 51.构建乘积数组
题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不 ...