国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Day43|動態(tài)規(guī)劃part05: 1049. 最后一塊石頭的重量 II、494. 目標(biāo)和、474. 一和零

這篇具有很好參考價值的文章主要介紹了Day43|動態(tài)規(guī)劃part05: 1049. 最后一塊石頭的重量 II、494. 目標(biāo)和、474. 一和零。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1049.?最后一塊石頭的重量?II

本題物品的重量為stones[i],物品的價值也為stones[i]。

對應(yīng)著01背包里的物品重量weight[i]和 物品價值value[i]。

  1. 確定dp數(shù)組以及下標(biāo)的含義

dp[j]表示容量(這里說容量更形象,其實就是重量)為j的背包,最多可以背最大重量為dp[j]。

  1. 確定遞推公式

01背包的遞推公式為:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

本題則是:dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);(與分割子集那題相同)

  1. dp數(shù)組如何初始化

既然 dp[j]中的j表示容量,那么最大容量(重量)(也就是target)是多少呢,就是所有石頭的重量和。

定為target15001即可, 也可以將數(shù)組相加再/2

  1. 確定遍歷順序

在動態(tài)規(guī)劃:關(guān)于01背包問題,你該了解這些?。L動數(shù)組) (opens new window)中就已經(jīng)說明:如果使用一維dp數(shù)組,物品遍歷的for循環(huán)放在外層,遍歷背包的for循環(huán)放在內(nèi)層,且內(nèi)層for循環(huán)倒序遍歷!

  1. 舉例推導(dǎo)dp數(shù)組
  2. 從0-1背包轉(zhuǎn)化成實際問題

最后dp[target]里是容量為target的背包所能背的最大重量。

那么分成兩堆石頭,一堆石頭的總重量是dp[target],另一堆就是sum - dp[target]。

在計算target的時候,target = sum / 2 因為是向下取整,所以sum - dp[target] 一定是大于等于dp[target]的。

那么相撞之后剩下的最小石頭重量就是 (sum - dp[target]) - dp[target]。

最終代碼:

class Solution {
    public int lastStoneWeightII(int[] stones) {
        //思想:讓重量相似的石頭相撞這樣得到的石頭更小
        int sum = 0;
        for(int stone : stones){
            sum += stone;
        }
        int target = sum / 2;//像下取整的,target一定小于等于sum - target
        int dp[] = new int [target + 1];
        for(int i = 0; i < stones.length; i++){
            for(int j = target; j >= stones[i]; j--){
                dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);
            }
        }
        return sum - dp[target] - dp[target];

    }
}

494. 目標(biāo)和

這題的重點在于怎么把正負(fù)符號問題轉(zhuǎn)化為定和->進(jìn)而轉(zhuǎn)化為0-1背包問題

本題要如何使表達(dá)式結(jié)果為target,

既然為target,那么就一定有 left組合 - right組合(添加負(fù)號的) = target。

left + right = sum,而sum是固定的。right = sum - left

公式來了, left - (sum - left) = target 推導(dǎo)出 left = (target + sum)/2 。

target是固定的,sum是固定的,left就可以求出來。

此時問題就是在集合nums中找出和為left的組合。(相當(dāng)于0-1背包問題)

有兩種解法,一個回溯,跟組合總和那題一樣,第二種解法就是動態(tài)規(guī)劃。

回溯

先空著,不剪枝會超時。

動態(tài)規(guī)劃

x = (target + sum) / 2

此時問題就轉(zhuǎn)化為,裝滿容量為x的背包,有幾種方法

dp五部曲

  1. 確定dp數(shù)組下標(biāo)及其含義

dp[j] 表示:填滿j(包括j)這么大容積的包,有dp[j]種方法

  1. 確定遞推公式

只要搞到nums[i],湊成dp[j]就有dp[j - nums[i]] 種方法。也就是說dp[j - nums[i]]渴望找到nums[i],這樣就符合要求了。因此遞推公式是:

所以求組合類問題的公式,都是類似這種:

dp[j] += dp[j - nums[i]]

這個公式在后面在講解背包解決排列組合問題的時候還會用到!

  1. 初始化dp數(shù)組

只要初始化dp[0]即可,填滿0的包,有1種方法,所以dp[0] = 1。

  1. 確定遍歷順序

跟之前的一維0-1背包一樣,先遍歷物品再遍歷背包,背包從后往前遍歷。

  1. 舉例推導(dǎo)dp數(shù)組

[外鏈圖片轉(zhuǎn)存中…(img-PMOiMxzQ-1713323607584)]

最終代碼:

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = Arrays.stream(nums).sum();
        //如果target的絕對值大于sum,那么是沒有方案的
        if (Math.abs(target) > sum) return 0;
        //如果(target+sum)除以2的余數(shù)不為0,也是沒有方案的
        if ((target + sum) % 2 == 1) return 0;
        

        int left = (sum + target) / 2;

        int dp[] = new int[left + 1];
        dp[0] = 1;
        for(int i = 0; i < nums.length;i++){
            for(int j = left; j >= nums[i]; j--){
                dp[j] += dp[j - nums[i]];
            }
        }
        return dp[left];
    }
}

這里注意兩個特殊情況, 一個是如果target的絕對值大于sum,那么是沒有方案的,另一個是如果(target+sum)除以2的余數(shù)不為0,也是沒有方案的。

474. 一和零

理解成多重背包的同學(xué)主要是把m和n混淆為物品了,感覺這是不同數(shù)量的物品,所以以為是多重背包。

但本題其實是01背包問題!

只不過這個背包有兩個維度,一個是m 一個是n,而不同長度的字符串就是不同大小的待裝物品。

dp五部曲

  1. 確定dp數(shù)組(dp table)以及下標(biāo)的含義

dp[i][j]:最多有i個0和j個1的strs的最大子集的大小為dp[i][j]

  1. 確定遞推公式

dp[i][j] 可以由前一個strs里的字符串推導(dǎo)出來,strs里的字符串有zeroNum個0,oneNum個1。

dp[i][j] 就可以是 dp[i - zeroNum][j - oneNum] + 1。

此時大家可以回想一下01背包的遞推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

對比一下就會發(fā)現(xiàn),字符串的zeroNum和oneNum相當(dāng)于物品的重量(weight[i]),字符串本身的個數(shù)相當(dāng)于物品的價值(value[i])。

  1. dp數(shù)組初始化

初始為0即可。

  1. 遍歷順序

外層for循環(huán)遍歷物品,內(nèi)層for循環(huán)遍歷背包容量且從后向前遍歷!文章來源地址http://www.zghlxwxcb.cn/news/detail-855952.html

for (string str : strs) { // 遍歷物品
    int oneNum = 0, zeroNum = 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);
        }
    }
}
  1. 舉例推導(dǎo)dp數(shù)組
class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        //dp[i][j]表示i個0和j個1時的最大子集
        int[][] dp = new int[m + 1][n + 1];
        int oneNum, zeroNum;
        for (String str : strs) {
            oneNum = 0;
            zeroNum = 0;
            for (char ch : str.toCharArray()) {
                if (ch == '0') {
                    zeroNum++;
                } else {
                    oneNum++;
                }
            }
            //倒序遍歷
            for (int i = m; i >= zeroNum; i--) {
                for (int j = n; j >= oneNum; j--) {
                    dp[i][j] = Math.max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
                }
            }
        }
        return dp[m][n];
    }
}

到了這里,關(guān)于Day43|動態(tài)規(guī)劃part05: 1049. 最后一塊石頭的重量 II、494. 目標(biāo)和、474. 一和零的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Day43|leetcode 1049.最后一塊石頭的重量II、494.目標(biāo)和、474.一和零

    Day43|leetcode 1049.最后一塊石頭的重量II、494.目標(biāo)和、474.一和零

    題目鏈接:1049. 最后一塊石頭的重量 II - 力扣(LeetCode) 視頻鏈接:動態(tài)規(guī)劃之背包問題,這個背包最多能裝多少?LeetCode:1049.最后一塊石頭的重量II_嗶哩嗶哩_bilibili 有一堆石頭,每塊石頭的重量都是正整數(shù)。 每一回合,從中選出任意兩塊石頭,然后將它們一起粉碎。假設(shè)

    2024年02月10日
    瀏覽(30)
  • 力扣第1049題 最后一塊石頭的重量Il c++ 動態(tài)規(guī)劃(01背包)

    1049. 最后一塊石頭的重量 II 中等 相關(guān)標(biāo)簽 有一堆石頭,用整數(shù)數(shù)組? stones ?表示。其中? stones[i] ?表示第? i ?塊石頭的重量。 每一回合,從中選出 任意兩塊石頭 ,然后將它們一起粉碎。假設(shè)石頭的重量分別為? x ?和? y ,且? x = y 。那么粉碎的可能結(jié)果如下: 如果? x

    2024年02月06日
    瀏覽(19)
  • 力扣:416. 分割等和子集 & 1049. 最后一塊石頭的重量 II (動態(tài)規(guī)劃)(二合一,一次吃透兩道題)

    力扣:416. 分割等和子集 & 1049. 最后一塊石頭的重量 II (動態(tài)規(guī)劃)(二合一,一次吃透兩道題)

    力扣:416. 分割等和子集 1049. 最后一塊石頭的重量 II 用的方法都是01背包解法,思路也是近乎一樣,這里就放在一起講解了(主要講解第一題,第二題大家可以直接自己AC)。01背包解法詳細(xì)講解請見上篇博客01背包問題(二) 給你一個 只包含正整數(shù) 的 非空 數(shù)組 nums 。請你判斷

    2024年01月20日
    瀏覽(22)
  • 【5.31 代隨_43day】 最后一塊石頭的重量 II、目標(biāo)和、一和零

    【5.31 代隨_43day】 最后一塊石頭的重量 II、目標(biāo)和、一和零

    力扣連接:1049. 最后一塊石頭的重量 II(中等) 和 416. 分割等和子集 (opens new window) 非常像了 圖解步驟 代碼 力扣連接:494. 目標(biāo)和(中等) 確定dp數(shù)組以及下標(biāo)的含義 dp[j] 表示:填滿j(包括j)這么大容積的包,有dp[j]種方法 確定遞推公式 只要搞到nums[i],湊成dp[j]就有dp[

    2024年02月07日
    瀏覽(22)
  • leetcode 1049. 最后一塊石頭的重量 II

    leetcode 1049. 最后一塊石頭的重量 II

    ? ? ? ? ?與分割等和子集類似,可以轉(zhuǎn)化為0-1背包問題。 本題也是需要將數(shù)組元素分成兩堆,區(qū)別在于本題需要使這兩堆的差值最小,而之前那題是需要兩堆差值為0。 ? ? ? ?? 使用之前的一維dp數(shù)組的思路,代碼如下:

    2024年02月13日
    瀏覽(20)
  • LeetCode 1049 最后一塊石頭的重量 II

    題目: 有一堆石頭,用整數(shù)數(shù)組 stones 表示。其中 stones[i] 表示第 i 塊石頭的重量。每一回合,從中選出任意兩塊石頭,然后將它們一起粉碎。假設(shè)石頭的重量分別為 x 和 y,且 x = y。那么粉碎的可能結(jié)果如下: 如果 x == y,那么兩塊石頭都會被完全粉碎; 如果 x != y,那么重

    2024年02月05日
    瀏覽(30)
  • LeetCode1049. 最后一塊石頭的重量 II

    一、題目 有一堆石頭,用整數(shù)數(shù)組 stones 表示。其中 stones[i] 表示第 i 塊石頭的重量。 每一回合,從中選出 任意兩塊石頭 ,然后將它們一起粉碎。假設(shè)石頭的重量分別為 x 和 y ,且 x = y 。那么粉碎的可能結(jié)果如下: 如果 x == y ,那么兩塊石頭都會被完全粉碎; 如果 x != y ,

    2024年02月10日
    瀏覽(22)
  • Leetcode 1049 最后一塊石頭的重量II

    Leetcode 1049 最后一塊石頭的重量II

    題意理解 : ????????有一堆石頭,用整數(shù)數(shù)組? stones ?表示。其中? stones[i] ?表示第? i ?塊石頭的重量。 ????????每一回合,從中選出 任意兩塊石頭 ,然后將它們一起粉碎。假設(shè)石頭的重量分別為? x ?和? y ,且? x = y 。 ? ? ? ? 思路轉(zhuǎn)化:我們可以將題目轉(zhuǎn)換為

    2024年01月16日
    瀏覽(20)
  • Leet code1049 最后一塊石頭的重量II

    1049 最后一塊石頭的重量II 【問題描述】 有一堆石頭,用整數(shù)數(shù)組 stones 表示。其中 stones[i] 表示第 i 塊石頭的重量。 每一回合,從中選出 任意兩塊石頭 ,然后將它們一起粉碎。假設(shè)石頭的重量分別為 x 和 y ,且 x = y 。那么粉碎的可能結(jié)果如下: 如果 x == y ,那么兩塊石頭

    2024年02月13日
    瀏覽(21)
  • leetcode 動態(tài)規(guī)劃(最后一塊石頭的重量II、目標(biāo)和、一和零)

    leetcode 動態(tài)規(guī)劃(最后一塊石頭的重量II、目標(biāo)和、一和零)

    力扣題目鏈接(opens new window) 題目難度:中等 有一堆石頭,每塊石頭的重量都是正整數(shù)。 每一回合,從中選出任意兩塊石頭,然后將它們一起粉碎。假設(shè)石頭的重量分別為 x 和 y,且 x = y。那么粉碎的可能結(jié)果如下: 如果 x == y,那么兩塊石頭都會被完全粉碎; 如果 x != y,那

    2024年02月03日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包