W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
Question
輸入一個數(shù)組
容器的容量等于高度和寬度的乘積(即面積),其中高度由較短的隔板決定,寬度是兩個隔板的數(shù)組索引之差。
請在數(shù)組中選擇兩個隔板,使得組成的容器的容量最大,返回最大容量。
圖 15-7 最大容量問題的示例數(shù)據(jù)
容器由任意兩個隔板圍成,因此本題的狀態(tài)為兩個隔板的索引,記為
根據(jù)題意,容量等于高度乘以寬度,其中高度由短板決定,寬度是兩隔板的索引之差。設(shè)容量為
設(shè)數(shù)組長度為
這道題還有更高效率的解法。如圖 15-8 所示,現(xiàn)選取一個狀態(tài)
圖 15-8 初始狀態(tài)
如圖 15-9 所示,若此時將長板
這是因?yàn)樵谝苿娱L板
圖 15-9 向內(nèi)移動長板后的狀態(tài)
反向思考,我們只有向內(nèi)收縮短板
圖 15-10 向內(nèi)移動短板后的狀態(tài)
由此便可推出本題的貪心策略:初始化兩指針分裂容器兩端,每輪向內(nèi)收縮短板對應(yīng)的指針,直至兩指針相遇。
圖 15-11 展示了貪心策略的執(zhí)行過程。
2.
和 3.
步,直至 圖 15-11 最大容量問題的貪心過程
代碼循環(huán)最多
變量
max_capacity.cpp
/* 最大容量:貪心 */
int maxCapacity(vector<int> &ht) {
// 初始化 i, j 分列數(shù)組兩端
int i = 0, j = ht.size() - 1;
// 初始最大容量為 0
int res = 0;
// 循環(huán)貪心選擇,直至兩板相遇
while (i < j) {
// 更新最大容量
int cap = min(ht[i], ht[j]) * (j - i);
res = max(res, cap);
// 向內(nèi)移動短板
if (ht[i] < ht[j]) {
i++;
} else {
j--;
}
}
return res;
}
之所以貪心比窮舉更快,是因?yàn)槊枯喌呢澬倪x擇都會“跳過”一些狀態(tài)。
比如在狀態(tài)
圖 15-12 移動短板導(dǎo)致被跳過的狀態(tài)
觀察發(fā)現(xiàn),這些被跳過的狀態(tài)實(shí)際上就是將長板
以上的分析說明,移動短板的操作是“安全”的,貪心策略是有效的。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: