最少攔截系統(HDU 1257)

2021-08-28 09:46:46 字數 2165 閱讀 1562

2.2 單調棧

將數列

\left\ \right\}

命題1:數列

\left\ \right\}

非遞增子串行的最小劃分數等於其最長遞增子串行的長度。

證明

設數列

\left\ \right\}

非遞增子串行的最小劃分數為k,數列

\left\ \right\}

最長遞增子串行的長度為p。

顯然最長遞增子串行中不可能有兩個數在同乙個劃分裡面,所以有k⩾p

k \geqslant p

k⩾p。

其次,可以在每個劃分裡面拿出乙個數出來,構成乙個遞增子串行(這裡暫時不解釋),這樣k⩽p

k \leqslant p

k⩽p。

綜上可推出k=p

k=pk=

p。命題2:數列

\left\ \right\}

遞增子串行的最小劃分數等於其最長非遞增子串行的長度。

命題3:數列

\left\ \right\}

非遞減子串行的最小劃分數等於其最長遞減子串行的長度。

命題4:數列

\left\ \right\}

遞減子串行的最小劃分數等於其最長非遞減子串行的長度。

d pi

dp_dp

i​表示以第i

ii個數結尾的最長遞增子串行的長度。

d pi

=max⁡j

⩽i−1

∧a

j

(aj)

+1

dp_= \max_ < a_}(a_)+1

dpi​

=maxj⩽

i−1∧

aj​​​(a

j​)+

1。最終要求的最長遞增子串行為max

1⩽i⩽

n(dp

i)

max_(dp_)

max1⩽i

⩽n​(

dpi​

)對於每個dpi

dp_dp

i​都需要在[1,

i−1]

[1,i-1]

[1,i−1

]中尋找最優解,所以時間複雜度為o(n

2)

\mathcal(n^)

o(n2)。

#include

#include

using

namespace std;

const

int n=

1e3+10;

int a[n]

,dp[n]

,n;int

main()

} res=

max(res,dp[i]);

}printf

("%d\n"

,res);}

return0;

}

最長遞增子串行也可以通過"單調棧"實現(事實上這不是真正意義上的單調棧,因為在操作過程中修改了棧中間的元素,破壞了fifo的性質)。這裡簡單介紹一下演算法,暫不作解釋:

對於每個需要入棧的元素,比較其與棧頂元素的大小

如果棧為空或比棧頂元素大,則直接入棧

否則,用其替換棧內第乙個大於或等於他的元素

最壞的情況下,每次的入棧元素都需要替換,替換過程中使用二分查詢,時間複雜度為olo

g(n)

\mathcal

olog(n

)。總的時間複雜度為o(n

log(

n)

)\mathcal(nlog(n))

o(nlog

(n))

#include

#include

#include

using

namespace std;

int n;

intmain()

printf

("%d\n"

,stk.

size()

);}return0;

}

hdu1257 最少攔截系統

解釋 當炮彈乙個接乙個的從空中飛來時,系統可以攔住比它攔住前乙個高度低的炮,比前乙個高的不攔,給第二個系統攔 problem description 某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統.但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能超過...

hdu 1257 最少攔截系統

題目大意 給定一串飛彈的高度,問最少需要多少飛彈攔截系統。思路 lis 分析 首先,至少需要一套攔截系統,一開始可以打到第一顆飛彈的位置。之後每來一顆飛彈更新一下系統能打到的高度。一旦有一顆飛彈所有系統都打不到了,增加乙個系統。那麼就會得到乙個序列,每個系統目前能打到的最高位置。這個序列是遞增的,後...

HDU1257 最少攔截系統

problem description 某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統.但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能超過前一發的高度.某天,雷達捕捉到敵國的飛彈來襲.由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有...