為了對抗附近惡意國家的威脅,r國更新了他們的飛彈防禦系統。
一套防禦系統的飛彈攔截高度要麼一直嚴格單調上公升要麼一直嚴格單調下降。
例如,一套系統先後攔截了高度為 3
33 和高度為 4
44的兩發飛彈,那麼接下來該系統就只能攔截高度大於 4
44 的飛彈。
給定即將襲來的一系列飛彈的高度,請你求出至少需要多少套防禦系統,就可以將它們全部擊落。
輸入格式
輸入包含多組測試用例。
對於每個測試用例,第一行包含整數 n
nn ,表示來襲飛彈數量。
第二行包含 n
nn 個不同的整數,表示每個飛彈的高度。
當輸入測試用例 n=0
n=0n=
0 時,表示輸入終止,且該用例無需處理。
輸出格式
對於每個測試用例,輸出乙個佔據一行的整數,表示所需的防禦系統數量。
資料範圍
1 ≤n
≤50
1 \leq n \leq 50
1≤n≤50
輸入樣例:
5
3 5 2 4 1
0
輸出樣例:
2
樣例解釋
對於給出樣例,最少需要兩套防禦系統。
一套擊落高度為 3,4
3,43,
4 的飛彈,另一套擊落高度為 5,2
,1
5,2,1
5,2,
1 的飛彈。
這道題與acwing1010.攔截飛彈的不同之處在於,本題可以使用不同的攔截系統,而那道題只能使用同一種攔截系統。
所以本題的大體思路與攔截飛彈第二問相同,都是通過貪心來進行構造答案,還要在貪心的外面套一層 dfs
dfsdf
s 用來決定哪種抉擇。
貪心思路:
對於嚴格單調上公升:從前往後掃瞄每乙個數,對於每個數:
如果現有子串行的結尾都大於等於當前數,則建立新的子串行。
將當前數放到結尾小於它的最大的子串行後面。
對於嚴格單調下降:從前往後掃瞄每乙個數,對於每個數:
如果現有子串行的結尾都小於等於當前數,則建立新的子串行。
將當前數放到結尾大於它的最小的子串行後面。
對這兩個貪心思路還要通過乙個 dfs
dfsdf
s 來進行決策,最終找到答案。
#include #include using namespace std;
const int n = 55;
int n;
int a[n];
int up[n], down[n];
int cnt;
void dfs(int u, int su, int sd)
int k = 0;
while(k < su && up[k] >= a[u]) k ++;
int t = up[k];
up[k] = a[u];
if (k < su) dfs(u + 1, su, sd);
else dfs(u + 1, su + 1, sd);
up[k] = t;
k = 0;
while(k < sd && down[k] <= a[u]) k ++;
t = down[k];
down[k] = a[u];
if (k < sd) dfs(u + 1, su, sd);
else dfs(u + 1, su, sd + 1);
down[k] = t;
}int main()
return 0;
}
o(2
n)
o(2^n)
o(2n)
其實,由於在 dfs
dfsdf
s 中加了一些剪枝,所以實際的複雜度不會高達 2
502^
250,所以不會超時。
AcWing 187 飛彈防禦系統
原題鏈結 考察 dfs dp 思路 很像noi1999的飛彈攔截,但是這道題的決策需要決定是加入上公升子串行還是下降子串行,然後判斷加入到哪乙個上公升子串行.多決策問題多用dp或搜尋,這道題用dp需要記錄的狀態有 當前第幾個數,當前上公升子串行個數,當前下降子串行個數,但關鍵是當前最優解不一定能推到...
ACwing 187 飛彈防禦系統 DFS
為了對抗附近惡意國家的威脅,r國更新了他們的飛彈防禦系統。一套防禦系統的飛彈攔截高度要麼一直 嚴格單調 上公升要麼一直 嚴格單調 下降。例如,一套系統先後攔截了高度為3和高度為4的兩發飛彈,那麼接下來該系統就只能攔截高度大於4的飛彈。給定即將襲來的一系列飛彈的高度,請你求出至少需要多少套防禦系統,就...
飛彈防禦系統
飛彈防禦系統 為了對抗附近惡意國家的威脅,r國更新了他們的飛彈防禦系統。一套防禦系統的飛彈攔截高度要麼一直嚴格單調上公升要麼一直嚴格單調下降。資料範圍 1 n 50 輸入樣例 5 3 5 2 4 1 0輸出樣例 2樣例解釋 對於給出樣例,最少需要兩套防禦系統。一套擊落高度為3,4的飛彈,另一套擊落高...