原題指路
俄羅斯套娃信封問題
給定一些標記了寬度和高度的信封,寬度和高度以整數對形式(w, h)
出現。當另乙個信封的寬度和高度都比這個信封大的時候,這個信封就可以放進另乙個信封裡,如同俄羅斯套娃一樣。
請計算最多能有多少個信封能組成一組「俄羅斯套娃」信封(即可以把乙個信封放到另乙個信封裡面)。
說明:
不允許旋轉信封。
困難題就直接參考一波官方題解……
首先,在套娃前進行準備工作,對信封按照第一維w
ww進行公升序排列,先得到乙個w
ww的遞增序列;
其次,為了防止後面迭代過程**錯,即保證當信封的w
ww相等時,僅會在乙個序列裡選中其中乙個信封,所以將信封的第二維h
hh作為次關鍵字將序列按降序排列(與第1步合併為以w
ww為主關鍵字,以h
hh為次關鍵字的快排);
在排序完成後,就可以開始套娃(bushi)動態規劃了,用dp[
i]dp[i]
dp[i
]表示當序列長度為i
ii時最外面一層信封的hhh;
動態規劃的步驟具體可以用二分實現(易證迭代過程中dp為嚴格單調遞增序列):
若當前信封的h
i>dp
[−1]
h_ > dp[-1]
hi>dp
[−1]
時,則dp[
len(
dp)+
1]=h
idp[len(dp)+1]=h_
dp[len
(dp)
+1]=
hi;
否則就二分求出ind
exindex
index使dp[
inde
x]≤h
i[ind
ex+1
]dp[index] \le h_ < dp[index+1]
dp[ind
ex]≤hi
[ind
ex+1
],且使dp[
inde
x]=h
idp[index] = h_
dp[ind
ex]=
hi。
最後返回len
(dp)
len(dp)
len(dp
)即可。
時間複雜度:o(n
logn)
o(n\log)
o(nlogn)
(注:快排和基於二分的動態規劃均為o(n
logn)
o(n\log)
o(nlogn)
)空間複雜度:o(n
)o(n)
o(n)
class
solution
:def
maxenvelopes
(self, envelopes: list[list[
int]])
->
int:
ifnot envelopes:
# 空列表直接返回
return
0 length =
len(envelopes)
envelopes.sort(key=
lambda x:
(x[0],
-x[1])
)# 按第一維公升序,第二位降序對信封進行快排
dp =
[envelopes[0]
[1]]
for i in
range(1
, length):if
(num :
= envelopes[i][1
])> dp[-1
]:else
:# 二分查詢部分
index = bisect.bisect_left(dp, num)
dp[index]
= num
return
len(dp)
俄羅斯套娃信封問題
給定一些標記了寬度和高度的信封,寬度和高度以整數對形式 w,h 出現。當另乙個信封的寬度和高度都比這個信封大的時候,這個信封就可以放進另乙個信封裡,如同俄羅斯套娃一樣。請計算最多能有多少個信封能組成一組 俄羅斯套娃 信封 即可以把乙個信封放到另乙個信封裡面 說明 不允許旋轉信封。示例 輸入 enve...
俄羅斯套娃信封問題
給定一些標記了寬度和高度的信封,寬度和高度以整數對形式 w,h 出現。當另乙個信封的寬度和高度都比這個信封大的時候,這個信封就可以放進另乙個信封裡,如同俄羅斯套娃一樣。請計算最多能有多少個信封能組成一組 俄羅斯套娃 信封 即可以把乙個信封放到另乙個信封裡面 說明 不允許旋轉信封。示例 輸入 enve...
俄羅斯套娃信封問題
題目 給定一些標記了寬度和高度的信封,寬度和高度以整數對形式 w,h 出現。當另乙個信封的寬度和高度都比這個信封大的時候,這個信封就可以放進另乙個信封裡,如同俄羅斯套娃一樣。請計算最多能有多少個信封能組成一組 俄羅斯套娃 信封 即可以把乙個信封放到另乙個信封裡面 說明 不允許旋轉信封。示例 輸入 e...