代码随想录训练营Day42

发布于:2024-06-24 ⋅ 阅读:(146) ⋅ 点赞:(0)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

今天是跟着代码随想录刷题的第42天,主要学了最后一块石头的重量2、目标和和一和零三个问题


提示:以下是本篇文章正文内容,下面案例可供参考

一、最后一块石头的重量2

思路:和0-1背包差不多,主要就是以一个二分之一的背包容量,看最多能放多少,能放离这个二分之一背包越近越好,然后就是让结果减去两个这个就是最终的答案。

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        vector<int> dp(15001, 0);
        int sum = 0;
        for (int i = 0; i < stones.size(); i++) sum += stones[i];
        int target = sum / 2;
        for (int i = 0; i < stones.size(); i++) { // 遍历物品
            for (int j = target; j >= stones[i]; j--) { // 遍历背包
                dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
            }
        }
        return sum - dp[target] - dp[target];
    }
};

二、目标和

思路:
假设加法的总和为x,那么减法对应的总和就是sum - x。
所以我们要求的是 x - (sum - x) = target
x = (target + sum) / 2
核心思路就是dp【i】表示有多少种方法能够装满这个容量为5的背包,然后dp【5】等于啥呢,等于上一个dp【5】(也就是没有放这一层东西的)加上上一层的dp【5-nums【5】】(就是上一层把这个新加的东西预留出来,这样这一层可以放这个东西)
还需要考虑dp【0】是什么的问题, dp【0】就是我从有一个东西的里面取,取的和为0有几种情况,很明显就一种,我直接不取就可以了,所以就是一种。

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int S) {
        int sum = 0;
        for (int i = 0; i < nums.size(); i++) sum += nums[i];
        if (abs(S) > sum) return 0; // 此时没有方案
        if ((S + sum) % 2 == 1) return 0; // 此时没有方案
        int bagSize = (S + sum) / 2;
        vector<int> dp(bagSize + 1, 0);
        dp[0] = 1;
        for (int i = 0; i < nums.size(); i++) {
            for (int j = bagSize; j >= nums[i]; j--) {
                dp[j] += dp[j - nums[i]];
            }
        }
        return dp[bagSize];
    }
};

三、一和零

思路:
这道题就是一个二维的背包,第一个for循环就是遍历物品
第二个第三个for循环都是遍历背包,所以要注意第二个第三个的for循环一定要注意倒序才行

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
    vector<vector<int>> dp(m+1,vector<int> (n+1,0));
    for(string str:strs)
    {
        int zeronum=0;
        int onenum=0;
        for(char c:str)
        {
            if(c=='0') zeronum++;
            else onenum++;
        }
        for(int i=m;i>=zeronum;i--)
        {
            for(int j=n;j>=onenum;j--)
            {
                dp[i][j]=max(dp[i][j],dp[i-zeronum][j-onenum]+1);
            }
        }
    }
    return dp[m][n];//我很想你
    }
};


网站公告

今日签到

点亮在社区的每一天
去签到