2024/08/01 每日一题

LeetCode LCP.40 心算挑战

方法1:动态规划

class Solution:
    def maxmiumScore(self, cards: List[int], cnt: int) -> int:
        n = len(cards); old, now = 1, 0
        # dp1[i][j] 前 1~i 个卡牌选择 j 个和为奇数的最大值
        dp1 = [[-sys.maxsize] * (cnt + 1) for _ in range(2)]
        cnt1 = [[0] * (cnt + 1) for _ in range(2)]
        # dp2[i][j] 前 1~i 个卡牌选择 j 个和为偶数的最大值
        dp2 = [[0] * (cnt + 1) for _ in range(2)]
        cnt2 = [[0] * (cnt + 1) for _ in range(2)]

        for i in range(1, n + 1):  # 对于每一个卡牌
            old, now = now, old  # 交换行序列
            for j in range(1, cnt + 1):
                if cards[i - 1] % 2 == 0:  # 当前数为偶数
                    dp1[now][j], cnt1[now][j] = self.find(dp1[old][j],  
                        dp1[old][j - 1] + cards[i - 1], cnt1[old][j], cnt1[old][j - 1])
                    dp2[now][j], cnt2[now][j] = self.find(dp2[old][j],
                        dp2[old][j - 1] + cards[i - 1], cnt2[old][j], cnt2[old][j - 1])
                else:  # 当前数为奇数
                    dp1[now][j], cnt1[now][j] = self.find(dp1[old][j],  
                        dp2[old][j - 1] + cards[i - 1], cnt1[old][j], cnt2[old][j - 1])
                    dp2[now][j], cnt2[now][j] = self.find(dp2[old][j],
                        dp1[old][j - 1] + cards[i - 1], cnt2[old][j], cnt1[old][j - 1])

        return dp2[now][cnt] if cnt2[now][cnt] == cnt else 0

    def find(self, num1: int, num2: int, c1: int, c2: int) -> List[int]:
        if num2 > num1:
            return [num2, c2 + 1]
        else:
            return [num1, c1]

方法2:贪心

class Solution:
    def maxmiumScore(self, cards: List[int], cnt: int) -> int:
        cards.sort(reverse=True)
        # 前 cnt 数字之和、最小偶数、最小奇数
        s, even, odd = 0, 0, 0
        for i in range(cnt):
            s += cards[i]
            if cards[i] % 2 == 0:
                even = cards[i]
            else:
                odd = cards[i]
        if s % 2 == 0:  # 前 cnt 个数字和为偶数
            return s
        if cnt == len(cards):
            return 0
        # 用 [cnt:] 中的最大偶数替代 [:cnt] 中最小奇数 odd
        # 用 [cnt:] 中的最大奇数替代 [:cnt] 中最小偶数 even
        ans = 0
        if cards[cnt] % 2 == 0:  # 只需找最大奇数
            ans = s - odd + cards[cnt]
            if even != 0:  # 前面有偶数
                ans = max(ans, s - even + self.find(cards[cnt + 1:], 1))
        else:  # 只需找最大偶数
            if even != 0:
                ans = s - even + cards[cnt]
            ans = max(ans, s - odd + self.find(cards[cnt + 1:], 0))
        return ans

        def find(self, arr: List[int], flag: int) -> int:
            for x in arr:
                if x % 2 == flag:
                    return x
            return 0
class Solution {
    public int maxmiumScore(int[] cards, int cnt) {
        Arrays.sort(cards);
        int n = cards.length, s = 0, even = 0, odd = 0;
        for(int i = n - 1; i > n - 1 - cnt; i--) {
            s += cards[i];
            if(cards[i] % 2 == 0) even = cards[i];
            else odd = cards[i];
        }
        if(s % 2 == 0) return s;
        if(cnt == cards.length) return 0;
        int ans = 0, end = n - 1 - cnt;
        if(cards[end] % 2 == 0) {
            ans = s - odd + cards[end];
            if(even != 0) // s 中不一定存在偶数
                ans = Math.max(ans, s - even + find(cards, end - 1, 1));
        } else {
            if(even != 0) // s 中不一定存在偶数
                ans = s - even + cards[end];
            ans = Math.max(ans, s - odd + find(cards, end - 1, 0));
        }
        return ans;
    }

    static int find(int[] arr, int start, int type) {
        while(start >= 0 && arr[start] % 2 != type) start--;
        return start == -1 ? 0 : arr[start];
    }
}
posted @   Koonan-Edogawa  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示