首页 > 其他分享 >(43/60)最后一块石头的重量Ⅱ、目标和、一和零

(43/60)最后一块石头的重量Ⅱ、目标和、一和零

时间:2024-03-21 23:59:02浏览次数:20  
标签:stones target int 重量 43 60 let sum dp

day43

最后一块石头的重量Ⅱ

leetcode:1049. 最后一块石头的重量 II

动态规划

思路

a-b + c-d + e-f = (a+c+e) - (b+d+f)

等效于两堆石头相碰,最小可能重量就是最接近平均的两堆相碰。

复杂度分析

时间复杂度:O(N^2)。

空间复杂度:O(N)。

代码实现

C++:

class Solution {
public:
/*
意义:放入总重为j的商品,得到最大价值为dp[j] 商品重量、价值都为stones[i]
递推:dp[j] = max(dp[j],dp[j - stones[i]] + stones[i])
初始化:为0
遍历:先商品后背包,倒序
*/
    int lastStoneWeightII(vector<int>& stones) {
        // 尽量凑成相等的两堆
        int sum = 0;
        for(int num:stones) sum += num;
        vector<int> dp(sum/2 + 1,0);
        for(int i = 0;i < stones.size();i++){
            for(int j = sum/2;j >= stones[i];j--){
                dp[j] = max(dp[j],dp[j - stones[i]] + stones[i]);
            }
        }
        // 相碰之后剩下大堆-小堆
        return ( sum - dp[sum/2] ) - dp[sum/2];
    }
};

TypeScript:

/**
类似分割等和子集
相碰之后剩下大堆减小堆

 */

function lastStoneWeightII(stones: number[]): number {
    let sum = 0;
    stones.forEach((num)=>sum += num);
    let target = Math.floor(sum/2);
    let dp = new Array(target + 1).fill(0);
    for(let i = 0;i < stones.length;i++){
        for(let j = target;j >= stones[i];j--){
            dp[j] = Math.max(dp[j],dp[j - stones[i]] + stones[i]);
        }
    }

    return (sum  - dp[target]) - dp[target];
};

目标和

leetcode:494. 目标和

动态规划

思路

求总和为j的种类数,就是dp[j]+=dp[j-nums[i]]

这里是组合问题,所以先遍历背包再遍历物品。

又因为可以无限取数字,所以正序遍历。

复杂度分析

时间复杂度:O(N^2)。

空间复杂度:O(N)。

代码实现

C++:

class Solution {
public:
/*
意义:总和为j的数,共有dp[j]种 
递推:dp[j] += dp[j - nums[i]] 累和
初始化:dp[0] = 1 其余为0 dp[0]不表示甚麽意义,但是需要有这个滚雪球起点
遍历:先物品后背包,倒序

背包大小=(sum + target)/2
*/
    int findTargetSumWays(vector<int>& nums, int target) {
        int sum = 0;
        for(int num : nums) sum += num;
        if(abs(target) > sum) return 0;
        if((target + sum) % 2 == 1) return 0;   // 背包大小决定两者之和一定是偶数才行
        int bagSize = (target + 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];
    }
};	

TypeScript:

/**
总和为j的总共有dp[j]种
dp[j] = dp[j - nums[i]]
dp[0] = 1 ;其余为0
先物品再背包

bagSize = (target + sum) / 2
 */

function findTargetSumWays(nums: number[], target: number): number {
    let sum = 0;
    nums.forEach((num) => sum += num);
    if(Math.abs(target) > sum) return 0;
    if((target + sum) % 2 === 1) return 0;  // bagSize不能为奇数
    const bagSize = (target + sum) / 2;
    const dp = new Array(bagSize + 1).fill(0);
    dp[0] = 1;
    for(let i = 0;i < nums.length;i++){
        for(let j = bagSize;j >= nums[i];j--){
            dp[j] += dp[j - nums[i]];
        }
    }

    return dp[bagSize];
};

一和零

leetcode:474. 一和零

动态规划

二维背包,容量有两个维度。

复杂度分析:

时间复杂度:O(N^2)。

空间复杂度:O(N)。

代码实现

C++:

class Solution {
public:
/*
意义:容量为i个0和j个1的最大子集大小为dp[i][j]
递推:dp[i][j] = max(dp[i][j],dp[i-x][j-y] + 1);
初始化:全为0
遍历:物品、背包,倒序
*/

    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 x = 0,y = 0;
            for(char c : str){
                if(c == '0') x++;
                else y++;
            }
            // 遍历物品()
            for(int i = m;i >= x;i--){
                for(int j = n;j >= y;j--){
                    dp[i][j] = max(dp[i][j] , dp[i-x][j-y] + 1);
                }
            }
        }

        return dp[m][n];
    }
};

TS:

/**
i个0和j个1容量的最大子集的大小为dp[i][j]
dp[i][j] = max(dp[i][j],dp[i-x][j-y] + 1)
全为0
物品、背包,倒序
 */

function findMaxForm(strs: string[], m: number, n: number): number {
    const dp : number[][] = new Array(m+1);
    for(let i = 0;i < m+1;i++){
        dp[i] = new Array(n+1).fill(0);
    }
    strs.forEach((str) => {
        let x:number = 0, y:number = 0;
        for(let char of str){
            if(char === "0") x++;
            else y++;
        }
        for(let i = m;i >= x;i--){
            for(let j = n;j >= y;j--){
                dp[i][j] = Math.max(dp[i][j],dp[i-x][j-y] + 1);
            }
        }
    })

    return dp[m][n];
};

标签:stones,target,int,重量,43,60,let,sum,dp
From: https://www.cnblogs.com/tazdingo/p/18088502

相关文章

  • (41/60)0-1背包(二维数组、一维数组)、分割等和子集
    有点抽象0-1背包卡码网:携带研究材料(第六期模拟笔试)动态规划思路二维:意义:0~i物品内,放进容量为j的背包,最大价值为dp[i][j]递推:dp[i][j]=max(dp[i-1][j-weight[i],dp[i-1][j])初始化:第一列为0,第一行j>=weight[0]时赋值为value[0]遍历:先背包再物品/先物品再背包均可(......
  • (46/60)单词拆分、多重背包
    day46单词拆分leetcode:139.单词拆分动态规划代码实现/*意义:长度为j的字符串能否被dict里的单词拼出为dp[j]递推:if(dp[j]&&j~i子串在dict里)dp[i]=true;初始化:dp[0]=true无意义,只是滚雪球起点;其余为false遍历:对顺序有要求,排列数,先背包后物品;可重复取,正序*/......
  • (45/60)爬楼梯进阶、零钱兑换、完全平方数
    day45爬楼梯进阶卡码网:爬楼梯(第八期模拟笔试)动态规划代码实现/*总和为j总共有dp[j]种方法(可重复选取、排列)dp[j]+=dp[j-nums[i]dp[0]=1;其余为0先背包再物品,正序*/#include<iostream>#include<vector>#include<algorithm>usingnamespacestd;intmain(){......
  • (44/60)完全背包、零钱兑换Ⅱ、组合总和Ⅳ
    day44完全背包卡码网:携带研究材料(第七期模拟笔试)动态规划思路完全背包,物品可以无限次取,正序遍历。复杂度分析时间复杂度:O(N^2)。空间复杂度:O(N)。代码实现#include<iostream>#include<algorithm>#include<vector>usingnamespacestd;/*给j的容量可重复选择的最......
  • (51/60)买卖股票的最佳时机含冷冻期、买卖股票的最佳时机含手续费
    day51买卖股票的最佳时期含冷冻期leetcode:309.买卖股票的最佳时机含冷冻期动态规划代码实现/*意义:下标为i时各种情况的收益dp[i][0]持有dp[i][1]当天卖出dp[i][2]之前不持有递推:dp[i][0]=max(dp[i-1][0],dp[i-1][2]-prices[i]);//之前持有、之前不持有且当......
  • (50/60)买卖股票的最佳时机Ⅲ、买卖股票的最佳时机Ⅳ
    day50买卖股票的最佳时机Ⅲleetcode:123.买卖股票的最佳时机III动态规划代码实现/*意义:下标为i时,不同状态收益为dp[i][0]未持有dp[i][1]第一次持有dp[i][2]第一次未持有dp[i][3]第二次持有dp[i][4]第二次未持有递推:dp[i][0]=dp[i-1][0];之前未持有dp[i]......
  • (48/60)买卖股票的最佳时机、买卖股票的最佳时机Ⅱ
    day48买卖股票的最佳时机leetcode:121.买卖股票的最佳时机动态规划代码实现/*意义:dp[i][0]下标为i天持有股票的最大收益;dp[i][1]下标为i天不持股的最大收益递推:之前买入、当天买入:dp[i][0]=max(dp[i-1][0],-prices[i]);之前卖出、当天卖出:dp[i][1]=max(dp[i-1][1],......
  • (47/60)打家劫舍、打家劫舍Ⅱ、打家劫舍Ⅲ
    day47打家劫舍leetcode:198.打家劫舍动态规划代码实现/*偷到下标为i的最大金额数为dp[i]偷i、不偷i:dp[i]=max(dp[i-2]+nums[i],dp[i-1]);dp[0]=nums[0];dp[1]=max(nums[0],nums[1]);正序遍历*/classSolution{public:introb(vector<int>&nums){......
  • 代码随想录算法训练营第五十三天| ● 1143.最长公共子序列 ● 1035.不相交的线 ●
    最长公共子序列 题目链接:1143.最长公共子序列-力扣(LeetCode)思路:。classSolution{public:intlongestCommonSubsequence(stringtext1,stringtext2){vector<vector<int>>dp(text1.size()+1,vector<int>(text2.size()+1,0));for(inti......
  • 1943+1944.Codeforces Round 934 (Div. 1,Div. 2) - sol
    20240321终于差不多把Div1补完了(F当然没补),第一次打Div1,还是出了一些小状况的。唉。没有补Div1F的逆天题,选择放弃。Dashboard-CodeforcesRound934(Div.2)-CodeforcesDashboard-CodeforcesRound934(Div.1)-Codeforces2A.DestroyingBridgesThere......