洛谷 P1020 導彈攔截 菜鳥題解
有志者,事竟成,破釜沉舟,百二秦關終屬楚。
苦心人,天不負,臥薪嚐膽,三千越甲可吞吳。
P1020 導彈攔截
題目連結:
https://www.luogu.com.cn/problem/P1020
題目解釋:
首先就是要找到一個最長非上升子序列,這是第一問,第二問就是非上升序列有多少個。
問題分析:
就是優化最長非上升子序列的問題,要求時間複雜度 n l o g n nlog_n nlogn, n 2 n^2 n2的時間複雜度會爆,所以得優化。
題目思路:
首先新建一個陣列dp[],和變數int,分別用來記錄非上升子序列,和當前最長非上升子序列的長度。
看樣例:
389 207 155 300 299 170 158 65
首先存在最長非上升子序列:389 300 299 170 158 65, 長度為6
其中207 155,這個序列需要第二套裝置
所以答案就是6 2
首先開始手動模擬
記住這是動態規劃題目,dp陣列只需要儲存一種狀態而不是準確的答案。
dp陣列中儲存一個非上升子序列,當出現一個小於 d p [ l e n ] dp[len] dp[len]的數字的時候,就執行 d p [ + + l e n ] = a [ i ] dp[++len] = a[i] dp[++len]=a[i],這時表明,當前最長長度發生變化,更新當前最長長度的最小值。
如果出現一個大於 d p [ l e n ] dp[len] dp[len]的數字 a [ i ] a[i] a[i]的時候,就使用二分查詢,在dp陣列中找到一個大於 a [ i ] a[i] a[i]的位置,然後把那個位置的數字替換為 a [ i ] a[i] a[i]。
這意味著,如果後面出了剛好比 a [ i ] a[i] a[i]小的序列,我就可以把原來的dp陣列給替換了,而替換的過程len的大小並不變。如果到時候len值變化了,說明一定有更長的新的序列出現了。如果我一直在替換dp陣列中的,但是len值沒變化,其實這個時候就相當於,我取得最長非上升子序列還是len值剛剛更新時的那個dp陣列。
第一個問題解決。
第二個問題:
怎麼解決多個非上升子序列:
和上一問思路差不多。新建一個陣列dp2[],然後只要有小的數字出現,就替換,如果有大的數字出現,就加在後面,有小的數字出現即 d p 2 [ l e n 2 ] > = a [ i ] dp2[len2] >= a[i] dp2[len2]>=a[i],說明當前的裝置可以滿足,裝置數量並不需要滿足,如果有大的數字出現即 d p 2 [ l e n 2 ] < a [ i ] dp2[len2] < a[i] dp2[len2]<a[i],說明當前的高度已經無法滿足,需要另外一套新的裝置,套用上一問的思路,直接二分就可以。
AC程式碼:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 7;
int f[N], d1[N], d2[N];
int main(){
ios::sync_with_stdio(false);
int n = 0, len1 = 1, len2 = 1;
while (cin >> f[++n]); n--;
d1[1] = d2[1] = f[1];
for (int i = 2; i <= n; i++){
//只要高度比當前裝置最後一次的高度低,那就可以繼續使用
if (d1[len1] >= f[i]) d1[++len1] = f[i];
else{
int p = upper_bound(d1 + 1, d1 + 1 + len1, f[i], greater<int> ()) - d1;
d1[p] = f[i];
}
//只要高度不提高,就不需要另外一套裝置
if (d2[len2] < f[i]) d2[++len2] = f[i];
else{
int p = lower_bound(d2 + 1, d2 + 1 + len2, f[i]) - d2;
d2[p] = f[i];
}
}
cout << len1 << " " << len2 << endl;
return 0;
}
需要注意兩個函式:
lower_bound(),找到第一個大於等於的數的位置,返回值為指標,並不是下標所以要減去首地址。
upper_bound(),找到第一個大於的數的位置,返回值同樣為指標。
相關文章
- 洛谷 P1020 導彈攔截
- [題解] [NOIP 1999] 導彈攔截
- 線性DP P1020 [NOIP1999 提高組] 導彈攔截
- 導彈攔截
- 「 題解 」P2487 [SDOI2011]攔截導彈
- P1254 導彈攔截
- 洛谷-P9574 題解
- 洛谷-P9830 題解
- 資訊學奧賽一本通 1322:攔截導彈問題(evd)
- 5211 導彈攔截 普及組 NOIP2010 暴力列舉
- 【題解】洛谷P1613: 跑路
- [題解][洛谷P3594] WIL
- [題解][洛谷P3584] LAS
- OpenJ_Bailian - 2945 攔截導彈(最長遞減子序列)AI
- 洛谷P10244 String Minimization 題解
- 洛谷P2440 木材加工 題解
- 洛谷 P1208混合牛奶 題解
- [題解] [洛谷P1404] 平均數
- 洛谷T90444 密碼 題解密碼
- 資訊學奧賽一本通 1289:攔截導彈(evd)
- 洛谷——玩具謎題
- 洛谷 P2280 鐳射炸彈
- 洛谷題單指南-動態規劃1-P1164 小A點菜動態規劃
- 【題解】洛谷P3118: Moovie Mooving G
- [題解][洛谷P1578] 奶牛浴場
- 洛谷 P4829 kry loves 2048——題解
- 洛谷P1496 火燒赤壁【題解】
- [題解][洛谷P1136] 迎接儀式
- [題解] [洛谷 P1174] 打磚塊
- 解決spring cloud Feign遠端呼叫服務,新增headers解決攔截器攔截問題SpringCloudHeader
- 洛谷八皇后問題
- 【題解】洛谷P2448: 無盡的生命
- 洛谷 P3034 Cow Photography G/S——題解
- 洛谷 P1516 青蛙的約會 題解
- 洛谷 P3596 [POI2015] MOD 題解
- [題解] [洛谷P1108] 低價購買
- 洛谷 p1605 迷宮問題 詳解
- 洛谷11月月賽題解(A-C)