快轉到主要內容

CSES-1073 Towers

目錄


題目連結:https://cses.fi/problemset/task/1073

題意
#

這題會給我們一系列不同大小的方塊,我們必須依照順序把它們疊成一座座的高塔。
疊塔的規定是:新來的方塊只能疊在比它嚴格還要大的方塊上方。
如果現有的塔都不符合條件,就只能為這個方塊建立一座新塔。
不過題目希望我們盡可能節省空間,目標是求出最少總共需要建幾座塔。

思路
#

這題可以使用貪婪法(Greedy)求解。
每次拿到新方塊時,將它疊在「剛好比它稍大」的塔頂,能最有效地節省塔的數量。
如果疊在過大的方塊上,就會限制該大方塊承載後續其他較大方塊的能力。

在實作上,我們可以維護一個陣列來記錄每座塔「最頂端的方塊大小」。
因為貪婪策略的特性,這個陣列會自然保持遞增的順序。
當新方塊進來時,在陣列中找出第一個比它還大的方塊並將其替換掉。
如果找不到比它大的,代表現有塔頂都偏低,必須將此方塊作為基底建立新塔。

程式碼
#

#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define fi first
#define se second
#define INF LONG_LONG_MAX/1000
#define WA() cin.tie(0)->sync_with_stdio(0)
#define all(x) (x).begin(), (x).end()
#define int long long
#define PII pair<int, int>

signed main() { WA();
    int n; cin >> n;
    vector<int> v(n);
    for (auto &i : v) cin >> i;
    
    // 記錄每座塔最頂端的方塊大小,陣列會自然維持遞增
    vector<int> g;
    for (auto &i : v) {
        // 尋找第一個比當前方塊還要大的塔頂,並將其替換
        if (auto it = upper_bound(all(g), i); it != g.end()) *it = i;
        // 若找不到適合的塔,只能建立一座新塔
        else g.pb(i);
    }
    
    // 陣列的長度即為最少需要的塔數
    cout << g.size() << '\n';
}
Piau 的筆記本
作者
Piau 的筆記本
希望我寫下來的東西能夠長久的記在我的腦中