題目: UVa - 1062 - Containers
題目說明
給一個字串,代表依序進到港口的貨物,後面的貨物進來後就無法再移動前面的貨物,在港口的貨物須從下而上按照字典序的大而小排序,求最少堆成幾堆可以滿足條件。
解題思路
解法一:
將港口的每堆貨物視為一個 Stack,每次貨物進來後先檢查能否放在原本的 Stack 上,若無法則新增一個 Stack 後放入。最後輸出 Stack 的個數即可。
解法二:
延續解法一的想法,可以發現由左到右的 Stack 的 top()
其實就是 LIS,所以 Stack 的數量即為 LIS ( 最長嚴格遞增子陣列 ) 的長度,使用 DP 找出長度即可。
參考解法
解法一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include <iostream> #include <vector> #include <string> #include <stack> #include <functional>
using namespace std;
static auto __ = [] { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); return 0; }();
int main() { int cnt = 0; string str; vector<stack<char>> v;
auto AddToStack = [&](char& ch) { for (auto& s : v) if (ch <= s.top()) { s.push(ch); return; } v.push_back(stack<char>()); v.back().push(ch); };
while (cin >> str && str != "end") { v.clear(); for (auto& ch : str) AddToStack(ch); cout << "Case " << ++cnt << ": " << v.size() << '\n'; } }
|
解法二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include <iostream> #include <vector> #include <algorithm>
using namespace std;
static auto __ = [] { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); return 0; }();
int main() { int cnt = 0; string in; while (cin >> in && in != "end") { int ret = 0, l = in.length(); vector<int> dp(l, 1); for (int i = 0; i < l; ++i) { for (int j = i + 1; j < l; ++j) if (in[j] > in[i]) dp[j] = max(dp[j], dp[i] + 1); ret = max(ret, dp[i]); } cout << "Case " << ++cnt << ": " << ret << '\n'; } }
|