365天挑战LeetCode1000题——Day 090 划分为k个相等的子集 收集足够苹果的最小花园周长 最长等差数列

698. 划分为k个相等的子集

365天挑战LeetCode1000题——Day 090 划分为k个相等的子集 收集足够苹果的最小花园周长 最长等差数列_第1张图片

代码实现(状态压缩 + 动态规划)

class Solution {
public:
    bool canPartitionKSubsets(vector<int>& nums, int k) {
        int all = accumulate(nums.begin(), nums.end(), 0);
        if (all % k > 0) {
            return false;
        }
        int per = all / k; 
        sort(nums.begin(), nums.end());
        if (nums.back() > per) {
            return false;
        }
        int n = nums.size();
        vector<bool> dp(1 << n, false);
        vector<int> curSum(1 << n, 0);
        dp[0] = true;
        for (int i = 0; i < 1 << n; i++) {
            if (!dp[i]) {
                continue;
            }
            for (int j = 0; j < n; j++) {
                if (curSum[i] + nums[j] > per) {
                    break;
                }
                if (((i >> j) & 1) == 0) {
                    int next = i | (1 << j);
                    if (!dp[next]) {
                        curSum[next] = (curSum[i] + nums[j]) % per;
                        dp[next] = true;
                    }
                }
            }
        }
        return dp[(1 << n) - 1];
    }
};

1954. 收集足够苹果的最小花园周长365天挑战LeetCode1000题——Day 090 划分为k个相等的子集 收集足够苹果的最小花园周长 最长等差数列_第2张图片

代码实现(贪心)

class Solution {
public:
    long long minimumPerimeter(long long neededApples) {
        vector<long long> nums;
        long long i;
        nums.push_back(0);
        for (i = 2; i <= 1000000; i += 2) {
            nums.push_back(nums.back() + 3 * i * i);
            if (nums.back() >= neededApples) break;
        }
        return i * 4;
    }
};

1027. 最长等差数列

365天挑战LeetCode1000题——Day 090 划分为k个相等的子集 收集足够苹果的最小花园周长 最长等差数列_第3张图片

代码实现(动态规划)

class Solution {
public:
    int longestArithSeqLength(vector<int>& nums) {
        int ans = 0;
        unordered_map<int, int> myMap;
        vector<vector<int>> dp(nums.size(), vector<int>(nums.size()));
        for (int i = 0; i < nums.size(); i++) {
            for (int j = i + 1; j < nums.size(); j++) {
                int target = 2 * nums[i] - nums[j];
                if (myMap.count(target)) {
                    dp[i][j] = dp[myMap[target]][i] + 1;
                }
                ans = max(ans, dp[i][j]);
            }
            myMap[nums[i]] = i;
        }
        return ans + 2;
    }
};

你可能感兴趣的:(LeetCode千题之路,算法,动态规划,leetcode)