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

算法 DAY45 動態(tài)規(guī)劃07 70. 爬樓梯 322. 零錢兌換 279. 完全平方數(shù) 139. 單詞拆分 多重背包

這篇具有很好參考價值的文章主要介紹了算法 DAY45 動態(tài)規(guī)劃07 70. 爬樓梯 322. 零錢兌換 279. 完全平方數(shù) 139. 單詞拆分 多重背包。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

70. 爬樓梯

和377. 組合總和 Ⅳ (opens new window)基本就是一道題了。本題代碼不長,題目也很普通,但稍稍一進階就可以考察完全背包

class Solution {
public:
    int climbStairs(int n) {
        vector<int> nums = {1,2};
        vector<int> dp(n+1,0);
        dp[0] = 1;
        for(int j = 0; j <=n; j++){
            for(int i = 0; i < nums.size(); i++){
                if(j >= nums[i]) dp[j] += dp[j - nums[i]];
            }
        }
        return dp[n];
    }
};

322. 零錢兌換

動態(tài)規(guī)劃五部曲
1、確定dp[j]的含義
dp[j] 湊成 j 的最少硬幣的個數(shù)
2、確定遞推公式
比如想湊成3,
如果手里有1,那么最小個數(shù)就是dp[2]+1
如果手里有2,那么最小個數(shù)就是dp[1]+1
如果手里有3,那么最小個數(shù)就是dp[0]+1
dp[j] = min(dp[j] , dp[j-nums[i]] + 1)
3、確定初始值
dp[0] = 0
其余值應(yīng)給 INT_MAX。
最終dp[j] == INT_MAX 就返回-1
4、確定遍歷順序
首先這是個完全背包,背包容量從小到大遍歷。其次,{5,5,1} 和{1,5,1}的組合大小都是3,所以兩層for循環(huán)無所謂遍歷順序。
5、驗證
coins = [1, 2, 5], amount = 11

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount+1,INT_MAX);
        dp[0] = 0;
        for(int j = 1; j <= amount; ++j){
            for(int i = 0; i < coins.size(); ++i){
                if(j >= coins[i] && dp[j - coins[i]] != INT_MAX) dp[j] = min(dp[j],dp[j - coins[i]] + 1);
            }
        }
        return dp[amount] == INT_MAX ? -1 : dp[amount];
    }
};

279. 完全平方數(shù)

1、dp[j] : 構(gòu)成 j 的完全平方數(shù)的最小數(shù)量
2、dp[j] = min( dp[j] , dp[j - i * i ] + 1)
3、初始化
1 <= n <= 104,所以dp[0]無意義
dp[1] = 1, 其余值給INT_MAX
4、完全背包,求個數(shù)所以不用管兩個for的內(nèi)外

class Solution {
public:
    int numSquares(int n) {
        vector<int> dp(n+1,INT_MAX);
        dp[0] = 0;
        dp[1] = 1;
       
        for(int i = 1; i <= n ; ++i){
            for(int j = i*i; j <= n; ++j){
                if(dp[j-i*i] != INT_MAX) dp[j] = min(dp[j], dp[j - i*i] + 1);
            }
        }
        return dp[n] ;
    }
};

139. 單詞拆分

本題與回溯中:分割回文子串的思路是一樣的,通過分割字符串,得到單詞,再去單詞列表中尋找該單詞是否存在。
回溯寫法:
其中的memory數(shù)組,與之前組合問題中的去重數(shù)組作用一致。本題中通過在對應(yīng)的位置設(shè)置false,來標記該字母后的字符串沒有可分割的方法。例如:
cat sand og,在index = 7的地方設(shè)置false(og),
cats and og,當再一次分割到index = 7的時候,就不再進入for循環(huán)判斷og有無合適的分割方法,而是直接通過memory[7] = false 返回false。
時間復(fù)雜度還是O(2n),但是比沒有memory數(shù)組的情況好很多。

namespace jj22 {
	class Solution {
	public:
		bool wordBreak(string s, vector<string>& wordDict) {
			unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
			vector<bool> memory(s.size(), 1); // -1 表示初始化狀態(tài)
			return backtracking(s, wordSet, 0,memory);
		}
		bool backtracking(string s,unordered_set<string>& wordSet,int startIndex, vector<bool>& memory) {
			if (startIndex >= s.size())return true;
			if (!memory[startIndex]) return memory[startIndex];
			for (int i = startIndex; i < s.size(); ++i) {
				string word = s.substr(startIndex, i - startIndex + 1);
				if (wordSet.find(word) != wordSet.end() && backtracking(s, wordSet, i + 1,memory)) {
					return true;
				}
			}
			memory[startIndex] = false; // 記錄以startIndex開始的子串是不可以被拆分的
			return false;
		}

	};
	void test() {
		string s = "catsandog";
		vector<string> wordDict = { "cats", "dog", "sand", "and", "cat" };
		Solution ss;
		bool temp = ss.wordBreak(s, wordDict);
		int a = 10;
	}
}

背包解法:
首先,本題的物品就是各個單詞,背包容量是字符串長度。由于物品可以重復(fù)拿取,所以是完全背包問題。
五部曲:
1、dp數(shù)組的含義
dp[j] : 長度為j 的字符串能否被單詞列表里的單詞組成
2、遞推公式
當 i < j 時,如果dp[i] = true(即 dp[i] 長度為 i 的字符串能否被單詞列表里的單詞組成),
并且 i+1 到 j 組成的單詞在列表中能找到,則dp[j] = true
3、初始化
dp[0] = true
其余為false
例如:

string s = "catsandog";
vector<string> wordDict = { "cats", "dog", "sand", "and", "cat" };

dp[2] , j = 2, i = 0時,0-2的cat可以被找到,并且依賴于dp[0],所以dp[0] 必須為true
4、遍歷順序
構(gòu)成字符串的單詞順序是唯一的,所以是求排列問題,{1,5}和{5,1}是兩種不同的答案。
所以外層遍歷背包,內(nèi)層遍歷物品。
5、舉例推導(dǎo)dp[i]
算法 DAY45 動態(tài)規(guī)劃07 70. 爬樓梯 322. 零錢兌換 279. 完全平方數(shù) 139. 單詞拆分 多重背包自己寫的:內(nèi)層遍歷直接就是單詞列表


	class Solution {
	public:
		bool wordBreak(string s, vector<string>& wordDict) {
			vector<bool> dp(s.size() + 1, 0);
			dp[0] = true;
			for (int j = 0; j <= s.size(); ++j) {
				for (int i = 0; i < wordDict.size(); ++i) {
					string temp = wordDict[i];
					if (j >= temp.size() && dp[j - temp.size()] == true && s.substr(j - temp.size(), temp.size()) == temp) dp[j] = true;
				}
			}
			return dp[s.size()];
		}

	};

卡哥寫的:內(nèi)層是在從0開始遍歷字符串,到 j 。看i-j組成的單詞能否被找到

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
        vector<bool> dp(s.size() + 1, false);
        dp[0] = true;
        for (int i = 1; i <= s.size(); i++) {   // 遍歷背包
            for (int j = 0; j < i; j++) {       // 遍歷物品
                string word = s.substr(j, i - j); //substr(起始位置,截取的個數(shù))
                if (wordSet.find(word) != wordSet.end() && dp[j]) {
                    dp[i] = true;
                }
            }
        }
        return dp[s.size()];
    }
};

多重背包理論基礎(chǔ)

每件物品最多有Mi件可用,把Mi件攤開,其實就是一個01背包問題了。
例如:

背包最大重量為10。

物品為:
重量 價值 數(shù)量
物品0 1 15 2
物品1 3 20 3
物品2 4 30 2

問背包能背的物品最大價值是多少?

和如下情況有區(qū)別么?
重量 價值 數(shù)量
物品0 1 15 1
物品0 1 15 1
物品1 3 20 1
物品1 3 20 1
物品1 3 20 1
物品2 4 30 1
物品2 4 30 1

毫無區(qū)別,這就轉(zhuǎn)成了一個01背包問題了,且每個物品只用一次。文章來源地址http://www.zghlxwxcb.cn/news/detail-432860.html

void test_multi_pack() {
    vector<int> weight = {1, 3, 4};
    vector<int> value = {15, 20, 30};
    vector<int> nums = {2, 3, 2};
    int bagWeight = 10;
    for (int i = 0; i < nums.size(); i++) {
        while (nums[i] > 1) { // nums[i]保留到1,把其他物品都展開
            weight.push_back(weight[i]);
            value.push_back(value[i]);
            nums[i]--;
        }
    }

    vector<int> dp(bagWeight + 1, 0);
    for(int i = 0; i < weight.size(); i++) { // 遍歷物品
        for(int j = bagWeight; j >= weight[i]; j--) { // 遍歷背包容量
            dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
        }
        for (int j = 0; j <= bagWeight; j++) {
            cout << dp[j] << " ";
        }
        cout << endl;
    }
    cout << dp[bagWeight] << endl;

}

到了這里,關(guān)于算法 DAY45 動態(tài)規(guī)劃07 70. 爬樓梯 322. 零錢兌換 279. 完全平方數(shù) 139. 單詞拆分 多重背包的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • day 45:爬樓梯進階版;322. 零錢兌換;279. 完全平方數(shù)

    day 45:爬樓梯進階版;322. 零錢兌換;279. 完全平方數(shù)

    假設(shè)你正在爬樓梯。需要 n 階你才能到達樓頂。 每次你可以爬 一步一個臺階,兩個臺階,三個臺階,…,直到 m個臺階。問有多少種不同的方法可以爬到樓頂呢? dp[j]:爬到j(luò)層一共有多少種方法。 遞推公式:dp[j] += dp[j - i]; dp[0] = 1; dp[i]:目標整數(shù)為i的背包所能湊的最少硬幣

    2024年02月07日
    瀏覽(30)
  • 算法訓(xùn)練第四十五天|70. 爬樓梯 (進階)、322. 零錢兌換、279.完全平方數(shù)

    算法訓(xùn)練第四十五天|70. 爬樓梯 (進階)、322. 零錢兌換、279.完全平方數(shù)

    題目鏈接:70. 爬樓梯 (進階) 參考:https://programmercarl.com/0070.%E7%88%AC%E6%A5%BC%E6%A2%AF%E5%AE%8C%E5%85%A8%E8%83%8C%E5%8C%85%E7%89%88%E6%9C%AC.html 假設(shè)你正在爬樓梯。需要 n 階你才能到達樓頂。 每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢? 注意:給定 n 是一個正整數(shù)

    2023年04月26日
    瀏覽(26)
  • 【Day45】代碼隨想錄之動態(tài)規(guī)劃part7—爬樓梯(進階)、零錢兌換、完全平方數(shù)

    【Day45】代碼隨想錄之動態(tài)規(guī)劃part7—爬樓梯(進階)、零錢兌換、完全平方數(shù)

    今天又是補打卡的一天,開沖!??! 今日任務(wù): 70.爬樓梯(進階) 322.零錢兌換 279.完全平方數(shù) 這道題之前做過一次,但是可以采用完全背包的問題來分析一遍。 卡瑪網(wǎng)題目:【57.爬樓梯】 這個題目其實是更難了一點,因為前面的題目都是每次要不爬1階樓梯,要不爬2階樓

    2024年03月25日
    瀏覽(32)
  • 第42天-DP-第九章● 70. 爬樓梯 (進階) ● 322. 零錢兌換 ● 279.完全平方數(shù)

    - LeetCode鏈接 假設(shè)你正在爬樓梯。需要 n 階你才能到達樓頂。 每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢? - LeetCode鏈接 給你一個整數(shù)數(shù)組 coins ,表示不同面額的硬幣;以及一個整數(shù) amount ,表示總金額。 計算并返回可以湊成總金額所需的 最少的硬

    2024年02月01日
    瀏覽(32)
  • 【動態(tài)規(guī)劃】322. 零錢兌換

    定義 要湊出金額n 至少要dp(coins,n)個硬幣 確定base case 目標金額為0 返回0 確定 狀態(tài) 也就是原問題和子問題中的變量,你每次抽取一個硬幣,都會導(dǎo)致目標金額減少,所以狀態(tài)就是目標金額 確定選擇,也就是導(dǎo)致狀態(tài)產(chǎn)生變化的行為,每次選一個硬幣都會導(dǎo)致目標金額的減少

    2024年02月10日
    瀏覽(21)
  • leetcode 動態(tài)規(guī)劃(爬樓梯、零錢兌換、完全平方數(shù))

    leetcode 動態(tài)規(guī)劃(爬樓梯、零錢兌換、完全平方數(shù))

    卡碼網(wǎng):57. 爬樓梯(opens new window) 假設(shè)你正在爬樓梯。需要 n 階你才能到達樓頂。 每次你可以爬至多m (1 = m n)個臺階。你有多少種不同的方法可以爬到樓頂呢? 注意:給定 n 是一個正整數(shù)。 輸入描述:輸入共一行,包含兩個正整數(shù),分別表示n, m 輸出描述:輸出一個整數(shù),表

    2024年01月17日
    瀏覽(26)
  • 算法 DAY44 動態(tài)規(guī)劃6 完全背包 518. 零錢兌換 II 377. 組合總和 Ⅳ

    算法 DAY44 動態(tài)規(guī)劃6 完全背包 518. 零錢兌換 II 377. 組合總和 Ⅳ

    有N件物品和一個最多能背重量為W的背包。第i件物品的重量是weight[i],得到的價值是value[i] 。每件物品都有無限個(也就是可以放入背包多次),求解將哪些物品裝入背包里物品價值總和最大。 完全背包和01背包問題唯一不同的地方就是,每種物品有無限件。 動規(guī)五步曲來分

    2024年02月01日
    瀏覽(25)
  • 力扣算法刷題Day44|動態(tài)規(guī)劃:完全背包問題 零錢兌換II 組合總和Ⅳ

    力扣題目:#518.零錢兌換II(完全背包組合問題) 刷題時長:7min 解題方法:動態(tài)規(guī)劃(完全背包) 復(fù)雜度分析 時間復(fù)雜度: O(mn),其中 m 是amount,n 是 coins 的長度 空間復(fù)雜度: O(m) 問題總結(jié) 對遞推公式的理解 本題收獲 題意轉(zhuǎn)換:純完全背包是湊成背包最大價值是多少,而本

    2024年02月13日
    瀏覽(27)
  • 算法Day38 | 動態(tài)規(guī)劃,509. 斐波那契數(shù), 70. 爬樓梯, 746. 使用最小花費爬樓梯

    動態(tài)規(guī)劃是一種解決問題的算法思想。它通常用于優(yōu)化問題,其中要求找到一個最優(yōu)解或最大化(最小化)某個目標函數(shù)。 動態(tài)規(guī)劃的核心思想是 將問題分解成更小的子問題,并通過存儲子問題的解來避免重復(fù)計算 。這樣,可以通過解決子問題來構(gòu)建原始問題的解。動態(tài)規(guī)

    2024年02月09日
    瀏覽(25)
  • Day 44 | 動態(tài)規(guī)劃 完全背包、518. 零錢兌換 II 、 377. 組合總和 Ⅳ

    Day 44 | 動態(tài)規(guī)劃 完全背包、518. 零錢兌換 II 、 377. 組合總和 Ⅳ

    題目 文章講解 視頻講解 完全背包和0-1背包的區(qū)別在于:物品是否可以重復(fù)使用 思路:對于完全背包問題,內(nèi)層循環(huán)的遍歷方式應(yīng)該是從weight[i]開始一直遍歷到V,而不是從V到weight[i]。這樣可以確保每種物品可以被選擇多次放入背包,從而求解完全背包問題。 對于完全背包問

    2024年02月20日
    瀏覽(27)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包