【DP】【斜率】滑雪場的纜車

LinkLink

JZOJJZOJ 12571257

DescriptionDescription

科羅拉州的Farmer Ron打算爲他的奶牛們建造一個滑雪場(雖然需要的設施僅僅是一部纜車)。建造一部纜車,需要從山腳到山頂立若干根柱子,並用鋼絲連結它們。你可以認爲相對於地面,柱子的高度可以忽略不計。每相鄰兩根柱子間都有鋼絲直接相連。顯然,所有鋼絲的任何一段都不能在地面之下。
爲了節省建造的費用,FR希望在工程中修建儘可能少的柱子。他在準備修建纜車的山坡上選定了N(2<=N<=5,000)個兩兩之間水平距離相等的點,並且測量了每個點的高度H(0<=H<=1,000,000,000)。並且,按照國家安全標準,相鄰兩根柱子間的距離不能超過K(1<=K<=N-1)個單位長度。柱子間的鋼絲都是筆直的。
FR希望你幫他計算一下,在滿足下列條件的情況下,他至少要修建多少根柱子:首先,所有的柱子都必須修建在他所選定的點上,且每一段鋼絲都必須高於地面或者正好跟地面相切。相鄰兩根柱子的距離不大於K個單位長度。當然,在第一個點與最後一個點上一定都要修建柱子。

InputInput

第1行: 兩個整數 N 和 K,用空格隔開
第2…N+1行: 每行包括一個正整數,第i+1行的數描述了第i個點的高度

OutputOutput

第1行: 輸出一個整數,即FR最少需要修建的柱子的數目

SampleSample InputInput

13 4
0
1
0
2
4
6
8
6
8
8
9
11
12

SampleSample OutputOutput

5

HintHint

FR最少要修建5根柱子(分別在第1,5,7,9,13個山坡上的點)。鋼絲在1-5,5-7,7-9以及12-13這4段上與地 面相切。
如果FR只在1,5,9,13這4個點修建柱子,那5-9這一段鋼絲就有一部分在地下。如果柱子建在1,7,13這3個點,雖然鋼絲都是在地面之上,但這兩段鋼絲的長度都超過了最大長度限制。對於這組輸入數據,找不到一個合法方案,使方案中需要修建的柱子的數目少於5根。

TrainTrain ofof ThoughtThought

DPDP
以一個點ii爲目標,我們看ii的前kk個單位長度中的點,是否能到點ii,取最小值
判斷是否能到點ii,可以通過斜率判斷(詳見codecode

CodeCode

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>

using namespace std;

int h[5005], f[5005], n, k;

double absx(double a, double b)
{return max(a, b) - min(a , b);}

bool check(int s, int e)
{
	double slope = (h[e] - h[s]) * 1.0 / (e - s);//計算斜率
	double hnow = h[s];//hnow表示按照斜率計算出的當前高度
	for (int i = s + 1; i < e; ++i)
	{
		hnow += slope;
		if (h[i] > hnow && absx(hnow, h[i]) > 0.0000001) return 0;//若是中間有一根柱子高度超出了這一條線,顯然就是不可行的
	}
	return 1;
}

int main()
{
	scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; ++i)
		scanf("%d", &h[i]);
	memset(f, 0x7f, sizeof(f));
	f[1] = 1; 	f[2] = 2;
	for (int i = 3; i <= n; ++i)
	{
		int last = i - k;
		if (last < 1) last = 1;
		for (int j = last; j < i; ++j)
			if (f[j] + 1 < f[i]) {
				if (check(j, i)) f[i] = min (f[j] + 1, f[i]);
		}
	}
	printf("%d", f[n]);
} 
發佈了224 篇原創文章 · 獲贊 35 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章