Re: [閒聊] 每日LeetCode已回收

看板Marginalman作者 (愛麗絲)時間2年前 (2023/01/31 10:29), 編輯推噓2(202)
留言4則, 4人參與, 2年前最新討論串212/719 (看更多)
1626. Best Team With No Conflicts 每個球員有分數及年齡,要挑出一支球隊 其中年齡比較大的隊員的分數不能比較小 問總分最高多少 有點像權重版的 longest nondecreasing subsequence 不過寫一寫覺得比想像中麻煩,不太像是 Medium 寫完才發現 n <= 1000 所以其實 O(n^2) 就會過了 首先照年齡排好序後,對於第 i 個球員 在他之前都是年齡比他小的 所以要在那些分數比他小的球員裡選 也就是 DP[i] = max_j (DP[j] + scores[i]) where scores[j] <= scores[i] 到這裡 O(n^2) 的演算法已經可以很容易寫出來了 不過我們可以維護一個 ordered_map 從 score 對應到能得到的總分 並且保持若 a < b 則 map[a] < map[b] 這可以藉由每次插入時都移除那些不符合的人來維護 這樣對於 scores[i] 而言我們只要花 logn 找到在 map 裡 比他小的最大 key 就可以了 因為一個球員最多插入和移除一次 所以最後的複雜度還是 O(nlogn) class Solution { public: int bestTeamScore(vector<int>& scores, vector<int>& ages) { int n = scores.size(); using T = pair<int, int>; vector<T> V(n); for (int i = 0; i < n; i++) V[i] = { ages[i], scores[i] }; sort(V.begin(), V.end()); map<int, int> M{{0, 0}}; // score -> total for (auto [_, sc]: V) { auto it = M.upper_bound(sc); it--; int total = sc + it->second; vector<int> rm; for (it++; it != M.end(); it++) { if (total < it->second) break; rm.push_back(it->first); } for (int r: rm) M.erase(r); M[sc] = total; } return prev(M.end())->second; } }; -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.112.16.175 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Marginalman/M.1675132165.A.97C.html

01/31 10:30, 2年前 , 1F
大師
01/31 10:30, 1F

01/31 10:39, 2年前 , 2F
大師
01/31 10:39, 2F

01/31 10:53, 2年前 , 3F
你們好優秀
01/31 10:53, 3F

01/31 11:02, 2年前 , 4F
大師
01/31 11:02, 4F
文章代碼(AID): #1Zs7q5by (Marginalman)
討論串 (同標題文章)
文章代碼(AID): #1Zs7q5by (Marginalman)