0
点赞
收藏
分享

微信扫一扫

leetcode做题---动态规划篇

言诗把酒 2022-01-21 阅读 34

一、01背包

416. 分割等和子集  

力扣

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int sum = 0;
        int size = nums.size();
        for (int i = 0; i < size; ++i) {
            sum += nums[i];
        }
        if (sum % 2 == 1) {
            return false;
        }
        int target = sum / 2;
        vector<vector<int>> dp(size + 1, vector<int>(target + 1, 0));
        if (nums[0] <= target) {
            dp[0][nums[0]] = 1;
        }
        for (int i = 1; i < size; ++i) {
            for (int j = 1; j <= target; ++j) {
                if (j > nums[i]) {
                    dp[i][j] = dp[i - 1][j - nums[i]] | dp[i - 1][j];
                }
                else {
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        return dp[size - 1][target];
    }
};

二、完全背包

322. 零钱兑换   

力扣

还没做完,用该法C++超时,需继续看其他二维数组的算法

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        // https://www.cnblogs.com/yxym2016/p/12758327.html
        // https://www.iteye.com/blog/yangliuy-1469399
       int n=coins.size();
        int INF=9999;
        vector<vector<int>> dp(n + 1, vector<int>(amount + 1, 0));
        //初始化,amount=0
        for (int i = 1; i <= n ; i++) {
            dp[i][0]=0;
        }
        //初始化,coins=0
        for (int i = 1; i <= amount; i++) {
            dp[0][i]=INF;
        }
        for (int i = 1; i <=n ; i++) {
            for (int j = 1; j <=amount ; j++) {
                //******************* 写法1 start
                dp[i][j] = dp[i-1][j]; //赋值的目的,dp[i][j]最烂的结果是dp[i - 1][j],一会用这个结果到for循环中去和不同的k下的dp[i][j]比,取个for循环中的最小值
                for (int k = 1; k <= j /coins[i - 1] ; k++) {
                      if(dp[i-1][j-k*coins[i-1]]!=INF){
                         dp[i][j] = min(dp[i][j], dp[i - 1][j - k* coins[i - 1]] + k);
                      }
                }
                //***************** 写法1 end
                //这里有一个问题:写法2是有问题的,问题在哪里?
                /** 写法2 start
                * for (int k = 1; k*coins[i-1]<=j ; k++) {
                *    if(dp[i-1][j-k*coins[i-1]]!=INF){
                *        dp[i][j]=Math.min(dp[i-1][j-k*coins[i-1]]+k,dp[i-1][j]);
                *    }
                * }
                * 写法2 end
                */
            }
        }
        return dp[n][amount]==INF?-1:dp[n][amount];
    }
};

 

举报

相关推荐

0 条评论