開啟章節選單
10154 Weights and Measures
題目連結
題目翻譯
Yertle 國王要用烏龜疊成一座王座,每隻烏龜都有各自的體重與承重力(承重力包含自己的體重在內,例如一隻體重 300g、承重力 1000g 的烏龜,背上最多能承受 700g 的烏龜)。請幫忙決定疊放順序,使疊起來的烏龜塔盡可能高。
輸入
標準輸入包含多行,每行是兩個以空白分隔的整數,分別代表一隻烏龜的體重與承重力(單位皆為公克),最多有 5,607 隻烏龜。
輸出
輸出一個整數,代表在不超過任何一隻烏龜承重力的前提下,最多能疊起的烏龜數量。
解題思路
這是經典的「最長鏈型」DP 問題:把烏龜依承重力由小到大排序(承重力小的要盡量放在塔的上層),用 dp[j] 表示「疊 j 隻烏龜(由上層往下疊)時,目前最上面這 j 隻烏龜的總重量最少是多少」,初始 dp[0] = 0、其餘為極大值。依承重力由小到大依序處理每隻烏龜 i(體重 w、承重力 s),從大到小更新 j:若 dp[j-1] + w ≤ s(代表這隻烏龜扛得住上面疊的 j-1 隻)且比目前的 dp[j] 更小,就用 dp[j-1] + w 更新 dp[j],並用 mx 記錄曾經成功更新過的最大 j。掃描完所有烏龜後,mx 就是答案。
程式碼
//author: Piau #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(); vector<PII> v; for (int a, b; cin >> a >> b;) v.pb({b, a}); sort(all(v)); vector<int> dp(v.size()+1, INF); dp[0] = 0; int mx = 0; for (int i = 0; i < v.size(); i++) { for (int j = v.size(); j > 0; j--) { if (dp[j-1]+v[i].se <= v[i].fi && dp[j-1]+v[i].se < dp[j]) { dp[j] = dp[j-1]+v[i].se; mx = max(mx, j); } } } cout << mx << '\n'; }