某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。
但是這種飛彈攔截系統有乙個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。
某天,雷達捕捉到敵國的飛彈來襲。
由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。
輸入飛彈依次飛來的高度(雷達給出的高度資料是不大於30000的正整數,飛彈數不超過1000),計算這套系統最多能攔截多少飛彈,如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。
輸入格式
共一行,輸入飛彈依次飛來的高度。
輸出格式
第一行包含乙個整數,表示最多能攔截的飛彈數。
第二行包含乙個整數,表示要攔截所有飛彈最少要配備的系統數。
輸入樣例:
389 207 155 300 299 170 158 65
輸出樣例:
6
2
引理:dilworth定理
「能覆蓋整個序列的最少的不上公升子串行的個數」等價於「該序列的最長上公升子串行長度」
同理即有:
「能覆蓋整個序列的最少的不下降子串行的個數」等價於「該序列的最長下降子串行長度」
即當乙個序列的不上公升子串行即此子串行滿足a[ i ] >=a[ i + 1] >= ......a[ n ]時,能覆蓋整個序列的不相交的最少的此序列個數等價於整個序列的最長嚴格單調上公升子串行長度。
同理有當乙個序列的不下公升子串行即此子串行滿足a[ i ] <=a[ i + 1] <= ......a[ n ]時,能覆蓋整個序列的不相交的最少的此序列個數等價於整個序列的最長嚴格單調下降子串行長度。
其逆命題也為正確。
o(2 * n ^ 2)做法
1 #include 2 #include 3 #include 4 #include 56using
namespace
std;78
const
int n = 1010;9
inta[n];
10int
f[n], g[n];
11int
n;12
13int
main()
1426
27 cout << res <2829 res = 0;30
for (int i = n - 1; i >= 0; i --)
3138
39 cout << res <40return0;
41 }
貪心做法證明即dilworth定理證明( o( 2 * nlogn ) )
用如下方式維護陣列s,陣列長度cnt,意為cnt個不上公升子串行。儲存的是每乙個不上公升子串行中的最後乙個數:
遍歷原序列,對於遍歷到的每乙個數x:
1.若x大於s中每乙個數,則新建乙個不上公升子串行,放入x;
2.否則,找到s中大於等於x的最小的數,將其替換。
由於s每次增加長度時,增加的數必然大於其前面s中的任何乙個數;且每次替換時,不改變x與被替換數左右相鄰兩數的相對大小關係,故s必然維持單調遞增。則s即為原序列的最長上公升子串行。
設a為用該貪心演算法得到的長度,b為最優解長度。
顯然b<=a(否則b就不是最優解)。
故只需證明a>=b。用調整法(微調法)。
若a=b,則a=b,顯然成立。
否則(即a!=b),必然可以找到兩方案中第乙個(以原序列的順序)不同之處(某數放在了不同的位置,且原序列中該數前的所有數在兩方案中放的位置皆相同),將該數在兩方案中所處的位置上的數(即該數本身)以及兩位置之後方案中的序列相互對調,結果所得方案仍為合法解。即我們將貪心演算法所得方案調整成了最優方案,且在調整過程中,方案的序列數沒有增加,故a>=b(a -> b,且a轉變為b的過程中a的大小沒有增加)。
當使用lower_bounder和upper_bounder時,若我們要求的是最大不上公升子串行長度或最大不下降子串行長度時,我們允許子串行中存在相等的元素,即使用upper_bounder;而當我們要求的是最大上公升子串行長度和最大下降子串行長度時,我們不允許子串行中存在相等的元素,即使用lower_bounder。
舉個栗子:當我們要求的是最大上公升子串行長度和最大下降子串行長度時,如果子串行中存在相等的元素那麼這個子串行就是不合法的所以我們不允許存在相等的元素,反之亦然。
AcWing 1010 攔截飛彈
解題思路 這道題目的第乙個問題就是求最長下降子串行,直接用乙個dp就可以了 而對於第二個問題,問最少用多少個系統可以攔截所有的飛彈,我剛還是的思路是不斷地去求最長下降子串行,指導飛彈被去完為止,但是後來我找到了這個思路的乙個bug,然後想我們可以直接維護乙個陣列,陣列裡面就是各自系統中最小的飛彈的高...
AcWing1010 攔截飛彈
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷達給出...
1010 攔截飛彈
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷達給出...