返回介绍

solution / 2800-2899 / 2813.Maximum Elegance of a K-Length Subsequence / README_EN

发布于 2024-06-17 01:02:59 字数 8556 浏览 0 评论 0 收藏 0

2813. Maximum Elegance of a K-Length Subsequence

中文文档

Description

You are given a 0-indexed 2D integer array items of length n and an integer k.

items[i] = [profiti, categoryi], where profiti and categoryi denote the profit and category of the ith item respectively.

Let's define the elegance of a subsequence of items as total_profit + distinct_categories2, where total_profit is the sum of all profits in the subsequence, and distinct_categories is the number of distinct categories from all the categories in the selected subsequence.

Your task is to find the maximum elegance from all subsequences of size k in items.

Return _an integer denoting the maximum elegance of a subsequence of _items_ with size exactly _k.

Note: A subsequence of an array is a new array generated from the original array by deleting some elements (possibly none) without changing the remaining elements' relative order.

 

Example 1:

Input: items = [[3,2],[5,1],[10,1]], k = 2
Output: 17
Explanation: In this example, we have to select a subsequence of size 2.
We can select items[0] = [3,2] and items[2] = [10,1].
The total profit in this subsequence is 3 + 10 = 13, and the subsequence contains 2 distinct categories [2,1].
Hence, the elegance is 13 + 22 = 17, and we can show that it is the maximum achievable elegance. 

Example 2:

Input: items = [[3,1],[3,1],[2,2],[5,3]], k = 3
Output: 19
Explanation: In this example, we have to select a subsequence of size 3. 
We can select items[0] = [3,1], items[2] = [2,2], and items[3] = [5,3]. 
The total profit in this subsequence is 3 + 2 + 5 = 10, and the subsequence contains 3 distinct categories [1,2,3]. 
Hence, the elegance is 10 + 32 = 19, and we can show that it is the maximum achievable elegance.

Example 3:

Input: items = [[1,1],[2,1],[3,1]], k = 3
Output: 7
Explanation: In this example, we have to select a subsequence of size 3. 
We should select all the items. 
The total profit will be 1 + 2 + 3 = 6, and the subsequence contains 1 distinct category [1]. 
Hence, the maximum elegance is 6 + 12 = 7.  

 

Constraints:

  • 1 <= items.length == n <= 105
  • items[i].length == 2
  • items[i][0] == profiti
  • items[i][1] == categoryi
  • 1 <= profiti <= 109
  • 1 <= categoryi <= n
  • 1 <= k <= n

Solutions

Solution 1: Greedy

We can sort all items by profit from large to small. First choose the first $k$ items and calculate the total profit $tot$. Use a hash table $vis$ to record the categories of these $k$ items, use a stack $dup$ to record the profits of the repeated categories in order, and use a variable $ans$ to record the current maximum elegance.

Next, we consider starting from the $k+1$ item. If its category is already in $vis$, it means that if we choose this category, the number of different categories will not increase, so we can skip this item directly. If there is no duplicate category before, we can also skip this item directly. Otherwise, we can consider replacing the top item of $dup$ stack (the item with the minimum profit in the duplicate category) with the current item, which can increase the total profit by $p - dup.pop()$ and increase the number of different categories by $1$, so we can update $tot$ and $ans$.

Finally, we return $ans$.

The time complexity is $O(n \times \log n)$ and the space complexity is $O(n)$, where $n$ is the number of items.

class Solution:
  def findMaximumElegance(self, items: List[List[int]], k: int) -> int:
    items.sort(key=lambda x: -x[0])
    tot = 0
    vis = set()
    dup = []
    for p, c in items[:k]:
      tot += p
      if c not in vis:
        vis.add(c)
      else:
        dup.append(p)
    ans = tot + len(vis) ** 2
    for p, c in items[k:]:
      if c in vis or not dup:
        continue
      vis.add(c)
      tot += p - dup.pop()
      ans = max(ans, tot + len(vis) ** 2)
    return ans
class Solution {
  public long findMaximumElegance(int[][] items, int k) {
    Arrays.sort(items, (a, b) -> b[0] - a[0]);
    int n = items.length;
    long tot = 0;
    Set<Integer> vis = new HashSet<>();
    Deque<Integer> dup = new ArrayDeque<>();
    for (int i = 0; i < k; ++i) {
      int p = items[i][0], c = items[i][1];
      tot += p;
      if (!vis.add(c)) {
        dup.push(p);
      }
    }
    long ans = tot + (long) vis.size() * vis.size();
    for (int i = k; i < n; ++i) {
      int p = items[i][0], c = items[i][1];
      if (vis.contains(c) || dup.isEmpty()) {
        continue;
      }
      vis.add(c);
      tot += p - dup.pop();
      ans = Math.max(ans, tot + (long) vis.size() * vis.size());
    }
    return ans;
  }
}
class Solution {
public:
  long long findMaximumElegance(vector<vector<int>>& items, int k) {
    sort(items.begin(), items.end(), [](const vector<int>& a, const vector<int>& b) {
      return a[0] > b[0];
    });
    long long tot = 0;
    unordered_set<int> vis;
    stack<int> dup;
    for (int i = 0; i < k; ++i) {
      int p = items[i][0], c = items[i][1];
      tot += p;
      if (vis.count(c)) {
        dup.push(p);
      } else {
        vis.insert(c);
      }
    }
    int n = items.size();
    long long ans = tot + 1LL * vis.size() * vis.size();
    for (int i = k; i < n; ++i) {
      int p = items[i][0], c = items[i][1];
      if (vis.count(c) || dup.empty()) {
        continue;
      }
      vis.insert(c);
      tot += p - dup.top();
      dup.pop();
      ans = max(ans, tot + (long long) (1LL * vis.size() * vis.size()));
    }
    return ans;
  }
};
func findMaximumElegance(items [][]int, k int) int64 {
  sort.Slice(items, func(i, j int) bool { return items[i][0] > items[j][0] })
  tot := 0
  vis := map[int]bool{}
  dup := []int{}
  for _, item := range items[:k] {
    p, c := item[0], item[1]
    tot += p
    if vis[c] {
      dup = append(dup, p)
    } else {
      vis[c] = true
    }
  }
  ans := tot + len(vis)*len(vis)
  for _, item := range items[k:] {
    p, c := item[0], item[1]
    if vis[c] || len(dup) == 0 {
      continue
    }
    vis[c] = true
    tot += p - dup[len(dup)-1]
    dup = dup[:len(dup)-1]
    ans = max(ans, tot+len(vis)*len(vis))
  }
  return int64(ans)
}
function findMaximumElegance(items: number[][], k: number): number {
  items.sort((a, b) => b[0] - a[0]);
  let tot = 0;
  const vis: Set<number> = new Set();
  const dup: number[] = [];
  for (const [p, c] of items.slice(0, k)) {
    tot += p;
    if (vis.has(c)) {
      dup.push(p);
    } else {
      vis.add(c);
    }
  }
  let ans = tot + vis.size ** 2;
  for (const [p, c] of items.slice(k)) {
    if (vis.has(c) || dup.length === 0) {
      continue;
    }
    tot += p - dup.pop()!;
    vis.add(c);
    ans = Math.max(ans, tot + vis.size ** 2);
  }
  return ans;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文