題目
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。
輸入飛彈依次飛來的高度(雷達給出的高度資料是 \le 50000≤50000的正整數),計算這套系統最多能攔截多少飛彈,如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。
輸入格式
1行,若干個整數(個數≤100000)
輸出格式
2行,每行乙個整數,第乙個數字表示這套系統最多能攔截多少飛彈,第二個數字表示如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。
輸入 #1 複製
389 207 155 300 299 170 158 65
輸出 #1 複製62
為了讓大家更好地測試n方演算法,本題開啟spj,n方100分,nlogn200分
每點兩問,按問給分
這是道 「最長上公升子串行 一類的問題」 題目分為兩個問題。
1.後面每一發炮彈都不能高於前一發的高度,所以是求最長不上公升子串行
2.求最少要幾套炮彈,是求** 最長上公升子串行** (這是乙個什麼定理來著,最長上公升子串行有多長,就是
最少需要幾套,可以自己拿樣例模擬下,很好懂)
做法:這裡用到 slt 裡的lower_bound與upper_bound(本質是運用二分,也可以自己寫個二分搜尋代替)
lower_bound:找出序列中第乙個>=x的數
upper_bound: 找出序列中第乙個>x的數
**先是 常寫的 o(n^2)寫法, 後是 o(nlogn)寫法。
#include
#include
using
namespace std;
int a[
100005];
int n;
int dp[
100005];
int dp2[
100005];
int ans1,ans2;
intmain()
} ans1 =
max(ans1,dp[i]);
}for
(int i=
1;i<=n;i++)}
ans2 =
max(ans2,dp2[i]);
} cout
}
//本來有注釋的,但是好像寫完沒儲存,懶的再寫了
#include
#include
#include
using
namespace std;
int n;
int a[
100005];
int b[
100005
],c[
100005];
intmain()
n--;int len1=
1,len2=1;
b[1]=a[1]
; c[1]
=a[1];
for(
int i=
2;i<=n;i++)if
(c[len2]
) c[
++len2]
=a[i]
;else
} cout
}
NOIP 攔截飛彈
題意很簡潔,一共兩問。第一問是求單個攔截系統最多能攔截多少個,根據題意即最長非上公升子串行。第二問有多少飛彈攔截系統才能攔截全部飛彈,即有多少最長非上公升子串行才能包括全部數。稍加思考即可得出最長上公升子串行的長度即為答案。本題的轉化思考和兩個求序列長度寫法要記一下 就我目前看到的題解貌似沒人這麼寫...
NOIP 2010 飛彈攔截
題目描述 經過 11 年的韜光養晦,某國研發出了一種新的飛彈攔截系統,凡是與它的距離不超過其工作半徑的飛彈都能夠被它成功攔截。當工作半徑為 0 時,則能夠攔截與它位置恰好相同的飛彈。但該飛彈攔截系統也存在這樣的缺陷 每套系統每天只能設定一次工作半徑。而當天的使用代價,就是所有系統工作半徑的平方和。某...
noip2010 飛彈攔截
經過11 年的韜光養晦,某國研發出了一種新的飛彈攔截系統,凡是與它的距離不超過其工作半徑的飛彈都能夠被它成功攔截。當工作半徑為0 時,則能夠攔截與它位置恰好相同的飛彈。但該飛彈攔截系統也存在這樣的缺陷 每套系統每天只能設定一次工作半徑。而當天的使用代價,就是所有系統工作半徑的平方和。某天,雷達捕捉到...