Ski Lift 缆车支柱

Description

Farmer Ron in Colorado is building a ski resort for his cows (though budget constraints dictate construction of just one ski lift). The lift will be constructed as a monorail and will connect a concrete support at the starting location to the support at the ending location via some number of intermediate supports, each of height 0 above its land. A straight-line segment of steel connects every pair of adjacent supports. For obvious reasons, each section of straight steel must lie above the ground at all points. Always frugal, FR wants to minimize the number of supports that he must build. He has surveyed the N (2 <= N <= 5,000) equal-sized plots of land the lift will traverse and recorded the integral height H (0 <= H <= 1,000,000,000) of each plot. Safety regulations require FR to build adjacent supports no more than K (1 <= K <= N - 1) units apart. The steel between each pair of supports is rigid and forms a straight line from one support to the next. Help FR compute the smallest number of supports required such that: each segment of steel lies entirely above (or just tangent to) each piece of ground, no two consecutive supports are more than K units apart horizontally, and a support resides both on the first plot of land and on the last plot of land.

科罗拉州的罗恩打算为他的奶牛们建造一个滑雪场,虽然需要的设施仅仅是一部缆车.建造一部缆车,需要从山脚到山顶立若干根柱子,并用钢丝连结它们.你可以认为相对于地面,柱子的高度可以忽略不计.每相邻两根柱子间都有钢丝直接相连.显然,所有钢丝的任何一段都不能在地面之下. 为了节省建造的费用,罗恩希望在工程中修建尽可能少的柱子.他在准备修建缆车的山坡上迭定了N(2≤N≤5000)个两两之间水平距离相等的点,并且测量了每个点的高度H(O≤日≤10^9).并且,按照国家安全标准,相邻两根柱子间的距离不能超过K(1≤K≤N-1)个单位长度.柱子间的钢丝都是笔直的. 罗恩希望你帮他计算一下,在满足下列条件的情况下,他至少要修建多少根柱子:首先,所有的柱子都必须修建在他所选定的点上,且每一段钢丝都必须高于地面或者正好跟地面相切.相邻两根柱子的距离不大于K个单位长度.当然,在第一个点与最后一个点上一定都要修建柱子.

Input

  • Line 1: Two space-separate integers, N and K

  • Lines 2..N+1: Line i+1 contains a single integer that is the height of plot i.

第1行:两个整数N和K,用空格隔开.

第2到N+1行:每行包括一个正整数,第i+l行的数描述了第i个点的高度.

Output

  • Line 1: A single integer equal to the fewest number of lift towers FR needs to build subject to the above constraints

输出一个整数,即罗恩最少需要修建的柱子的数目.

Sample Input 1

13 4

0

1

0

2

4

6

8

6

8

8

9

11

12

Sample Output 1

5

思路:

dp状态转移方程:

dp[i] 表示在i点最少建立的柱子

dp[i] 就等于 dp[i-k] ~ dp[i-1] 上建立的最少的柱子数 + 1

计算斜率,判断两个点是否能连接

AC代码

#include<bits/stdc++.h>
#define eps 1e-6
using namespace std; typedef long long ll;
const int maxn = 5010;
int n,k;
ll h[maxn];
ll dp[maxn]; /*
线性dp状态转移方程:
dp[i] 表示在i点最少建立的柱子
dp[i] 就等于 dp[i-k] ~ dp[i-1] 上建立的最少的柱子数 + 1
*/ //判断起点e 和 终点s 是否能建立一个连线 (当且仅当 e 和 s连起来的线段上没有经过其他柱子)
bool check(int s,int e){
double h1=h[s],k=(h[e]-h[s])*1.0/(e-s); //k表示斜率 h表示当前高度
for(int i=s+1;i<e;i++){
h1+=k;
if(h1<h[i]&&fabs(h1-h[i])>eps)return 0;
}
return true;
} int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%lld",&h[i]);
memset(dp,0x3f3f3f,sizeof(dp));//要求dp的最小值 先要初始化为无穷大
dp[1] = 1;
dp[2] = 2;
for(int i=3;i<=n;i++){
for(int j=max(1,i-k);j<i;j++){
if(dp[i] > dp[j] + 1 && check(j,i)) dp[i] = dp[j] + 1;
}
}
printf("%lld\n",dp[n]);
return 0;
}

BZOJ-1721|线性dp-缆车支柱的更多相关文章

  1. LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

    问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...

  2. Codeforces 176B (线性DP+字符串)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...

  3. hdu1712 线性dp

    //Accepted 400 KB 109 ms //dp线性 //dp[i][j]=max(dp[i-1][k]+a[i][j-k]) //在前i门课上花j天得到的最大分数,等于max(在前i-1门 ...

  4. 动态规划——线性dp

    我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...

  5. POJ 2479-Maximum sum(线性dp)

    Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 33918   Accepted: 10504 Des ...

  6. poj 1050 To the Max(线性dp)

    题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...

  7. nyoj44 子串和 线性DP

    线性DP经典题. dp[i]表示以i为结尾最大连续和,状态转移方程dp[i] = max (a[i] , dp[i - 1] + a[i]) AC代码: #include<cstdio> ...

  8. 『最大M子段和 线性DP』

    最大M子段和(51nod 1052) Description N个整数组成的序列a[1],a[2],a[3],-,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M &g ...

  9. 『最长等差数列 线性DP』

    最长等差数列(51nod 1055) Description N个不同的正整数,找出由这些数组成的最长的等差数列. 例如:1 3 5 6 8 9 10 12 13 14 等差子数列包括(仅包括两项的不 ...

随机推荐

  1. windy数

    windy数指的是相邻两位差至少为2的数.问区间[a,b]中有多少个windy数 调了半个多小时,不过调出来之后对数位dp理解大大加深 #include<iostream> #includ ...

  2. Mybatis-Plus 3.0代码生成器

    package com.kyplatform.generator; import com.baomidou.mybatisplus.core.exceptions.MybatisPlusExcepti ...

  3. U盘制作系统盘的方法:

    1, 使用 u 盘制作 ubuntu16.04 的方法, 安装软件后,直接使用软件将 U盘制作成系统盘就好了 [1] 下载安装工具: UltraISO  官网:  http://www.ezbsyst ...

  4. 第四周Java作业

    老师说让用二维数组找最大,也就是最大和块,要求必须挨着,我其实不会写这个程序,所以我只能把自己的思路写出来 我觉得可以大问题缩小,我的思路是先把四个数一个正方形来进行计算,然后六个数矩形,把他化成两个 ...

  5. #WEB安全基础 : HTTP协议 | 0x11 HTTP的分块传输模块

    HTTP通信中,请求的编码实体资源没全部传输完成之前,浏览器无法显示页面,所以传输大容器数据时,把数据分块,能让浏览器逐步显示页面,这就叫分块传输模块 请看分块传输的流程图 每一块都会用十六进制来标记 ...

  6. dubbo搭建

    1.安装java : yum install java 2.下载Tomcat: wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-9/v9.0.1 ...

  7. orcl数据库锁等级研究小记

    上周通过orcl 悲观锁的方式解决了一个并发临界值的问题.现在来研究下orcl各中锁的机制以及如何手动释放锁. 首先,通过查阅资料,先了解下数据的的各种操作语言分类. SQL语言共分为四大类:数据查询 ...

  8. 查看Python、flask 版本

    查看Django版本检查是否安装成功,可以在dos下查看Django版本. 1.输入python 2.输入import django3.输入django.get_version() 查看flask版本 ...

  9. NGUI之实现连连看小游戏

    一,部分游戏规则如下: 二,代码如下: 1. 游戏逻辑核心代码 using System.Collections.Generic; using UnityEngine; namespace Modul ...

  10. Openstack oslo.config【一】

    OpenStack的项目貌似越来越多了,在Grizzly版之前,每个项目都得实现一套处理配置文件的代码.在每个项目的源码中基本上都可以找到openstack/common/cfg.py,inipars ...