1. 程式人生 > 其它 >【力扣】中國銀聯專場周賽

【力扣】中國銀聯專場周賽

中國銀聯專場

銀聯-03. 理財產品

某公司計劃推出一批投資專案。 product[i] = price 表示第 i 個理財專案的投資金額 price 。客戶在按需投資時,需要遵循以下規則:

  • 客戶在首次對專案 product[i] 投資時,需要投入金額 price
  • 對已完成首次投資的專案 product[i] 可繼續追加投入,但追加投入的金額需小於上一次對該專案的投入(追加投入為大於 0 的整數)
  • 為控制市場穩定,每人交易次數不得大於 limit。(首次投資追加投入均記作 1 次交易)

若對所有理財專案中最多進行 limit 次交易,使得投入金額總和最大,請返回這個最大值的總和。

注意:

  • 答案需要以 1e9 + 7 (1000000007)
    為底取模,如:計算初始結果為:1000000008,請返回 1

示例 1:

輸入:product = [4,5,3], limit = 8

輸出:26

解釋:滿足條件的一種情況為:
第一個理財專案進行金額為 4,3,2 的交易;
第二個理財專案進行金額為 5,4,3 的交易;
第三個理財專案進行金額為 3,2 的交易;
得到最大投入金額總和為 5 + 4 * 2 + 3 * 3 + 2 * 2 = 26。

示例 2:

輸入:product = [2,1,3], limit = 20

輸出:10

解釋:可交易總次數小於 limit,因此進行所有交易
第一個理財專案可交易 2 次,交易的金額分別為 2,1;
第二個理財專案可交易 1 次,交易的金額分別為 1;
第三個理財專案可交易 3 次,交易的金額分別為 3,2,1;
因此所得最大投入金額總和為 3 + 2 * 2 + 1 * 3 = 10。

提示:

  • 1 <= product.length <= 10^5
  • 1 <= product[i] <= 10^7
  • 1 <= limit <= 10^9

二分

我們把 p 看作不同高度的柱子,我們需要確定某個高度劃一刀,高的全選,少的從這個高度補。如果比這個高度低,那麼就會超過 limit 個。

class Solution:
    def maxInvestment(self, p: List[int], limit: int) -> int:
        # 二分上界和下界
        a, b = 0, max(p)
        while a < b:
            mid = (a + b) // 2
            # 高的高度
            count = 0
            for tmp in p:
                if tmp > mid:
                    count += tmp - mid
            # 多了,不行
            if count > limit:
                a = mid + 1
            # 少了,行
            else:
                b = mid
        print(b)
        ans, count = 0, 0
        for tmp in p:
            if tmp > b:
                # 記錄個數
                count += tmp - b
                # 高的全選,等差數列求和
                ans += (tmp - b) * (b + 1 + tmp) // 2
        # 不足的從這一層選
        ans += b * (limit - count)
        return ans % 1000000007

銀聯-04. 合作開發

為了不斷提高使用者使用的體驗,開發團隊正在對產品進行全方位的開發和優化。
已知開發團隊共有若干名成員,skills[i] 表示第 i 名開發人員掌握技能列表。如果兩名成員各自擁有至少一門對方未擁有的技能,則這兩名成員可以「合作開發」。
請返回當前有多少對開發成員滿足「合作開發」的條件。由於答案可能很大,請你返回答案對 10^9 + 7 取餘的結果。

注意:

  • 對於任意 skills[i] 均升序排列。

示例 1:

輸入:
skills = [[1,2,3],[3],[2,4]]

輸出: 2

解釋:
開發成員 [1,2,3] 和成員 [2,4] 滿足「合作開發」的條件,技能 14 分別是對方未擁有的技術
開發成員 [3] 和成員 [2,4] 滿足「合作開發」的條件,技能 34 分別是對方未擁有的技術
開發成員 [1,2,3] 和成員 [3] 不滿足「合作開發」的條件,由於開發成員 [3] 沒有對方未擁有的技術
因此有 2 對開發成員滿足「合作開發」的條件。

示例 2:

輸入:
skills = [[3],[6]]

輸出: 1

解釋:
開發成員 [3] 和成員 [6] 滿足「合作開發」的條件
因此有 1 對開發成員滿足「合作開發」的條件。

提示:

  • 2 <= skills.length <= 10^5
  • 1 <= skills[i].length <= 4
  • 1 <= skills[i][j] <= 1000
  • skills[i] 中不包含重複元素

逆向考慮 + 雜湊

假如 a 和 b 不能合作,而且 a 的技能比 b 多(或相等),那麼說明什麼, b 的技能 a 都有。那麼 a 的技能是 1 2 3 ,b 的技能就是 1,2,3 的子集。

class Solution:
    def coopDevelop(self, skills: List[List[int]]) -> int:
      	# 排序後 a 不能合作的都在前面,後面也會有不能和 a 合作的
        # 把這個看成有序方便討論
        skills.sort(key=lambda x : len(x))
        n = len(skills)
        hash = defaultdict(int)
        # 所有組合個數
        ans = n * (n - 1) // 2
        # print(skills)
        # list is unhashable,tuple is hashable
        hash[tuple(skills[0])] += 1
        # 遍歷每個員工
        for i in range(1, n):
            # 得到所有子集
            for j in range(len(skills[i])):
                # combinations(skills[i], j + 1) skills[i] 中 j + 1 個元素的所有組合
                for c in combinations(skills[i], j + 1):
                    ans -= hash[tuple(c)]
            # 進入雜湊表
            hash[tuple(skills[i])] += 1
        return ans % 1_000_000_007

如果是 cpp 呢?怎麼搞?好在最多隻有 4 個 skill ,數值在 1 到 1000 ,也就是說一個 skill 可以用 10 bit 表示,最多需要 40 bit 。

class Solution {
    unordered_map<long long, int> hash;
public:
    int coopDevelop(vector<vector<int>>& skills) {
        sort(skills.begin(), skills.end(), [&](vector<int> &a, vector<int> &b){return a.size() < b.size();});
        int n = skills.size();
        long long ans = n;
        ans = ans * (n - 1) / 2;
        long long s = 0;
        for (int i = 0; i < n; i++) {
            // 二進位制列舉,確定每個數選或者
            for (int j = 1; j < 1 << skills[i].size(); j++) {
                s = 0;
                for (int k = 0; k < skills[i].size(); k++) {
                    if (((j >> k) & 1) == 1) {
                        s = (s << 10) + skills[i][k];
                    }
                }
                ans -= hash[s];
            }
            hash[s] += 1;
        }
        return ans % 1000000007;
    }
};