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

算法基礎(chǔ)復(fù)盤筆記Day09【動(dòng)態(tài)規(guī)劃】—— 背包問題

這篇具有很好參考價(jià)值的文章主要介紹了算法基礎(chǔ)復(fù)盤筆記Day09【動(dòng)態(tài)規(guī)劃】—— 背包問題。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

? 作者主頁:歡迎來到我的技術(shù)博客??
? 個(gè)人介紹:大家好,本人熱衷于Java后端開發(fā),歡迎來交流學(xué)習(xí)哦!( ̄▽ ̄)~*
?? 如果文章對(duì)您有幫助,記得關(guān)注點(diǎn)贊收藏、評(píng)論??????
?? 您的支持將是我創(chuàng)作的動(dòng)力,讓我們一起加油進(jìn)步吧?。?!????

第一章 背包問題

一、01背包問題

1. 題目描述

有 N 件物品和一個(gè)容量是 V 的背包。每件物品只能使用一次。

第 i 件物品的體積是 v i v_i vi?,價(jià)值是 w i w_i wi?

求解將哪些物品裝入背包,可使這些物品的總體積不超過背包容量,且總價(jià)值最大。
輸出最大價(jià)值。

輸入格式

第一行兩個(gè)整數(shù),N,V,用空格隔開,分別表示物品數(shù)量和背包容積。

接下來有 N 行,每行兩個(gè)整數(shù) v i , w i v_i,w_i vi?,wi?,用空格隔開,分別表示第 ii 件物品的體積和價(jià)值。

輸出格式

輸出一個(gè)整數(shù),表示最大價(jià)值。

數(shù)據(jù)范圍

0 < N , V ≤ 1000 0<N,V≤1000 0<N,V1000
0 < v i , w i ≤ 1000 0<v_i,w_i≤1000 0<vi?,wi?1000

輸入樣例

4 5
1 2
2 4
3 4
4 5

輸出樣例:

8

2. 思路分析

版本一: 二維數(shù)組
(1)狀態(tài) f[i][j] 定義: i i i 個(gè)物品,背包容量是 j j j 下的最優(yōu)解(最大價(jià)值)

  • 當(dāng)前的狀態(tài)依賴于之前的狀態(tài),可以理解為從初始狀態(tài) f[0][0] = 0 開始決策,有 N 件物品,則需要 N 次決 策,每一次對(duì)第 i i i 件物品的決策,狀態(tài) f[i][j] 不斷由之前的狀態(tài)更新而來。

(2) 當(dāng)前背包容量不夠(j < v[i]),沒得選,因此前 i i i 個(gè)物品最優(yōu)解即為前 i ? 1 i?1 i?1 個(gè)物品最優(yōu)解:

  • 狀態(tài)轉(zhuǎn)移方程:f[i][j] = f[i - 1][j]

(3) 當(dāng)前背包容量夠,可以選,因此需要決策選與不選第 i i i 個(gè)物品:

  • 選:f[i][j] = f[i - 1][j - v[i]] + w[i]
  • 不選:f[i][j] = f[i - 1][j]
  • 我們的決策是如何取到最大價(jià)值,因此以上兩種情況取 最大值。

代碼如下:

#include<bits/stdc++.h>

using namespace std;

const int N = 1010;
int v[N];    // 體積
int w[N];    // 價(jià)值 
int f[N][N];  // f[i][j], j體積下前i個(gè)物品的最大價(jià)值 

int main() 
{
    int n, m;   
    cin >> n >> m;
    for(int i = 1; i <= n; i++) 
        cin >> v[i] >> w[i];

    for(int i = 1; i <= n; i++) 
        for(int j = 1; j <= m; j++)
        {
            //  當(dāng)前背包容量裝不進(jìn)第i個(gè)物品,則價(jià)值等于前i-1個(gè)物品
            if(j < v[i]) 
                f[i][j] = f[i - 1][j];
            // 能裝,需進(jìn)行決策是否選擇第i個(gè)物品
            else    
                f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);
        }           

    cout << f[n][m] << endl;

    return 0;
}

版本二: 一維數(shù)組
將狀態(tài) f[i][j] 優(yōu)化到一維 f[j],實(shí)際上只需要做一個(gè)等價(jià)變形。

為什么可以這樣變形呢?我們定義的狀態(tài) f[i][j] 可以求得任意合法的 i i i j j j 最優(yōu)解,但題目只需要求得最終狀態(tài) f[n][m] ,因此我們只需要一維的空間來更新狀態(tài)。

(1) 狀態(tài) f[j] 定義:N 件物品,背包容量 j j j 下的最優(yōu)解。

(2) 注意枚舉背包容量 j j j 必須從 m m m 開始。

(3) 為什么一維情況下枚舉背包容量需要逆序? 在二維情況下,狀態(tài) f[i][j] 是由上一輪i - 1的狀態(tài)得來的,f[i][j]f[i - 1][j] 是獨(dú)立的。而優(yōu)化到一維后,如果我們還是正序,則有f[較小體積] 更新到f[較大體積],則有可能本應(yīng)該用第i-1 輪的狀態(tài)卻用的是第 i 輪的狀態(tài)。

(4) 例如,一維狀態(tài)第 i 輪對(duì)體積為 3 的物品進(jìn)行決策,則 f[7]f[4] 更新而來,這里的 f[4] 正確應(yīng)該是 f[i - 1][4],但從小到大枚舉j這里的 f[4] 在第i輪計(jì)算卻變成了 f[i][4]。當(dāng)逆序枚舉背包容量j時(shí),我們求 f[7] 同樣由 f[4] 更新,但由于是逆序,這里的 f[4] 還沒有在第 i 輪計(jì)算,所以此時(shí)實(shí)際計(jì)算的 f[4] 仍然是 f[i - 1][4]。

(5) 簡單來說,一維情況正序更新狀態(tài) f[j] 需要用到前面計(jì)算的狀態(tài)已經(jīng)被「污染」,逆序則不會(huì)有這樣的問題。

(6) 狀態(tài)轉(zhuǎn)移方程: f[j] = max(f[j], f[j - v[i]] + w[i]

for(int i = 1; i <= n; i++) 
    for(int j = m; j >= 0; j--)
    {
        if(j < v[i]) 
            f[i][j] = f[i - 1][j];  // 優(yōu)化前
            f[j] = f[j];            // 優(yōu)化后,該行自動(dòng)成立,可省略。
        else    
            f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);  // 優(yōu)化前
            f[j] = max(f[j], f[j - v[i]] + w[i]);                   // 優(yōu)化后
    }  

實(shí)際上,只有當(dāng)枚舉的背包容量 j>= v[i] 時(shí)才會(huì)更新狀態(tài),因此我們可以修改循環(huán)終止條件進(jìn)一步優(yōu)化。

for(int i = 1; i <= n; i++)
    for(int j = m; j >= v[i]; j--)  
        f[j] = max(f[j], f[j - v[i]] + w[i]);

關(guān)于狀態(tài) f[j] 的補(bǔ)充說明:
二維下的狀態(tài)定義 f[i][j] 是前 i i i 件物品,背包容量 j j j 下的最大價(jià)值。一維下,少了前 i i i 件物品這個(gè)維度,我們的代碼中決策到第 i i i 件物品(循環(huán)到第i輪),f[j] 就是前i輪已經(jīng)決策的物品且背包容量 j j j 下的最大價(jià)值。

因此當(dāng)執(zhí)行完循環(huán)結(jié)構(gòu)后,由于已經(jīng)決策了所有物品,f[j] 就是所有物品背包容量 j j j 下的最大價(jià)值。即一維 f[j] 等價(jià)于二維 f[n][j]


版本三: 優(yōu)化輸入
我們注意到在處理數(shù)據(jù)時(shí),我們是一個(gè)物品一個(gè)物品,一個(gè)一個(gè)體積的枚舉。

因此我們可以不必開兩個(gè)數(shù)組記錄體積和價(jià)值,而是邊輸入邊處理。
代碼如下:

#include<bits/stdc++.h>

using namespace std;

const int N = 1010;
int f[N];  

int main() 
{
    int n, m;   
    cin >> n >> m;

    for(int i = 1; i <= n; i++) {
        int v, w;
        cin >> v >> w;      // 邊輸入邊處理
        for(int j = m; j >= v; j--)
            f[j] = max(f[j], f[j - v] + w);
    }

    cout << f[m] << endl;

    return 0;
}

3. 代碼實(shí)現(xiàn)

#include <bits/stdc++.h>

using namespace std;

const int N = 1010;

int n, m;
int v[N], w[N];
int f[N];

int main()
{
    cin >> n >> m;
    
    for (int i = 1; i <= n; i ++) cin >> v[i] >> w[i];
    
    for (int i = 1; i <= n; i ++)
        for (int j = m; j >= v[i]; j --)
            f[j] = max(f[j], f[j - v[i]] + w[i]);
    
    cout << f[m] << endl;
    
    return 0;
}

二、完全背包問題

1. 題目描述

有 N 種物品和一個(gè)容量是 V 的背包,每種物品都有無限件可用。

i i i 種物品的體積是 v i v_i vi?,價(jià)值是 w i w_i wi?

求解將哪些物品裝入背包,可使這些物品的總體積不超過背包容量,且總價(jià)值最大。
輸出最大價(jià)值。

輸入格式

第一行兩個(gè)整數(shù),N,V,用空格隔開,分別表示物品種數(shù)和背包容積。

接下來有 N 行,每行兩個(gè)整數(shù) v i , w i v_i,w_i vi?,wi?,用空格隔開,分別表示第 i i i 種物品的體積和價(jià)值。

輸出格式

輸出一個(gè)整數(shù),表示最大價(jià)值。

數(shù)據(jù)范圍

0 < N , V ≤ 1000 0<N,V≤1000 0<N,V1000
0 < v i , w i ≤ 1000 0<v_i,w_i≤1000 0<vi?,wi?1000

輸入樣例

4 5
1 2
2 4
3 4
4 5

輸出樣例:

10

2. 思路分析

版本一: 二維數(shù)組
狀態(tài)變量:f[i][j] 表示前 i i i 件物品放入容量為 j j j 的背包的最大價(jià)值。

當(dāng)前背包容量為 j j j,我們要考慮 i i i 件物品能否放入?是否放入?

  1. 當(dāng)前背包容量 j < w[i],不能放入,則 f[i][j] = f[i - 1][j]

  2. 當(dāng)前背包容量 j > w[i],能放入,但要考慮代價(jià)

    • 若第 i i i 件物品不放入背包,則 f[i][j] = f[i - 1][j]
    • 若第 i i i 件物品放入背包,則 f[i][j] = f[i][j - w[i]] + c[i]

對(duì)于前 i i i 件物品,背包容量為 j - w[i] 時(shí)可能已經(jīng)放入了第 i i i 件物品,容量為 j j j 時(shí)還可以再放入第 i i i 件物品,所以用 f[i][j - w[i]] 更新 f[i][j]。

代碼實(shí)現(xiàn)如下:

for (int i = 1; i <= n; i ++)
    {
        for (int j = 1; j <= m; j ++)
        {
            if (j < w[i])
                f[i][j] = f[i - 1][j];
            else
                f[i][j] = max(f[i - 1][j], f[i][j - w[i]] + c[i]);
        }
    }
    cout << f[n][m] << endl;

版本二: 一維數(shù)組
用一維數(shù)組 f[j] 只記錄一行數(shù)據(jù),讓 j j j 值順序循環(huán),順序更新 f[j]值。

for (int i = 1; i <= n; i ++)
    {
        for (int j = 1; j <= m; j ++)
        {
            if (j < w[i])
                f[j] = f[j];
            else
                f[j] = max(f[j], [j - w[i]] + c[i]);
        }
    }
    cout << f[m] << endl;

實(shí)際上,只有當(dāng)枚舉的背包容量 j>= v[i] 時(shí)才會(huì)更新狀態(tài),因此我們可以修改循環(huán)終止條件進(jìn)一步優(yōu)化。

 for (int i = 1; i <= n; i ++)
        for (int j = v[i]; j <= m; j ++)
            f[j] = max(f[j], f[j - v[i]] + w[i]);

3. 代碼實(shí)現(xiàn)

#include <bits/stdc++.h>

using namespace std;

const int N = 1010;

int n, m;
int v[N], w[N];
int f[N];

int main()
{
    cin >> n >> m;
    
    for (int i = 1; i <= n; i ++) cin >> v[i]>> w[i];
    
    for (int i = 1; i <= n; i ++)
        for (int j = v[i]; j <= m; j ++)
            f[j] = max(f[j], f[j - v[i]] + w[i]);
    
    cout << f[m] << endl;
    
    return 0;
}

三、多重背包問題I

1. 題目描述

有 N 種物品和一個(gè)容量是 V 的背包。

i i i 種物品最多有 s i s_i si? 件,每件體積是 v i v_i vi?,價(jià)值是 w i w_i wi?。

求解將哪些物品裝入背包,可使物品體積總和不超過背包容量,且價(jià)值總和最大。
輸出最大價(jià)值。

輸入格式

第一行兩個(gè)整數(shù),N,V,用空格隔開,分別表示物品種數(shù)和背包容積。

接下來有 N 行,每行三個(gè)整數(shù) v i , w i , s i v_i,w_i,s_i vi?,wi?,si?,用空格隔開,分別表示第 i i i 種物品的體積、價(jià)值和數(shù)量。

輸出格式

輸出一個(gè)整數(shù),表示最大價(jià)值。

數(shù)據(jù)范圍

0 < N , V ≤ 100 0<N,V≤100 0<N,V100
0 < 0< 0<v_i,w_i,s_i ≤ 100 ≤100 100

輸入樣例

4 5
1 2 3
2 4 1
3 4 3
4 5 2

輸出樣例:

10

2. 思路分析

01背包:第 i i i 種物品可以取0件、取1件。
多重背包:第 i i i 種物品可以取0件、取1件、取2件…取 s i s_i si?件。
多重背包問題轉(zhuǎn)化為01背包求解:把第 i i i 種物品換成 s i s_i si? 件01背包中的物品,每件物品的體積為 k ? v i k * v_i k?vi?,價(jià)值為 k ? w i k * w_i k?wi?(0 ≤ \leq k ≤ \leq s i s_i si?)


3. 代碼實(shí)現(xiàn)

#include <bits/stdc++.h>

using namespace std;

const int N = 110;

int n, m;
int v[N], w[N], s[N];
int f[N][N];

int main()
{
    cin >> n >> m;
    
    for (int i = 1; i <= n; i ++) cin >> v[i] >> w[i] >> s[i];
    
    for (int i = 1; i <= n; i ++)
        for (int j = 0; j <= m; j ++)
            for (int k = 0; k <= s[i] && k * v[i] <= j; k ++)
                f[i][j] = max(f[i][j], f[i - 1][j - v[i] * k] + w[i] * k);
    
    cout << f[n][m] << endl;
    
    return
}

四、多重背包問題 II

1. 題目描述

有 N 種物品和一個(gè)容量是 V 的背包。

i i i 種物品最多有 s i s_i si? 件,每件體積是 v i v_i vi?,價(jià)值是 w i w_i wi?。

求解將哪些物品裝入背包,可使物品體積總和不超過背包容量,且價(jià)值總和最大。
輸出最大價(jià)值。

輸入格式

第一行兩個(gè)整數(shù),N,V,用空格隔開,分別表示物品種數(shù)和背包容積。

接下來有N 行,每行三個(gè)整數(shù) v i , w i , s i v_i,w_i,s_i vi?,wi?,si?,用空格隔開,分別表示第 i i i 種物品的體積、價(jià)值和數(shù)量。

輸出格式

輸出一個(gè)整數(shù),表示最大價(jià)值。

數(shù)據(jù)范圍

0 < N ≤ 1000 0<N≤1000 0<N1000
0 < V ≤ 2000 0<V≤2000 0<V2000
0 < 0< 0<v_i,w_i,s_i ≤ 2000 ≤2000 2000
提示:

本題考查多重背包的二進(jìn)制優(yōu)化方法。

輸入樣例

4 5
1 2 3
2 4 1
3 4 3
4 5 2

輸出樣例:

10

2. 思路分析

二進(jìn)制優(yōu)化方法的例子:
假設(shè)有50個(gè)蘋果,現(xiàn)在要取 n n n 個(gè)蘋果( n n n ≤ \leq 50),如何???樸素的作家應(yīng)該是將蘋果一個(gè)一個(gè)拿出來,知道 n n n 個(gè)蘋果被取出來。

二進(jìn)制優(yōu)化的思想就是:再假設(shè)有5個(gè)蘋果和6只箱子,利用箱子繼續(xù)某些預(yù)備工作,可以在每個(gè)箱子中放 2 k 2^k 2k(k ≥ \geq 0)個(gè)蘋果,也就是1、2、4、8、16、19(剩余的數(shù)),取任意 n n n 個(gè)蘋果時(shí),只需要推出幾只箱子就可以了。例如:取20個(gè)蘋果,只需要拿出2個(gè)箱子(1、19),這樣的話原來20次操作的現(xiàn)在變成2次操作就可以了。

二進(jìn)制拆分思想:
將第 i i i 種物品拆分成若干件物品,每件物品的體積和價(jià)值乘以一個(gè)拆分系數(shù)(1, 2 1 2^1 21, 2 2 2^2 22 2 k ? 1 2^{k-1} 2k?1, s i ? 2 k + 1 s_i - 2^k + 1 si??2k+1),就可以轉(zhuǎn)化成01背包的物品求解。

例如: s i = 12 s_i = 12 si?=12,拆分系數(shù)為 1 , 2 , 4 , 5 1,2,4,5 1,2,4,5,轉(zhuǎn)化成4件01背包的物品: ( v i , w i ) (v_i, w_i) (vi?,wi?) ( 2 v i , 2 w i ) (2v_i, 2w_i) (2vi?,2wi?)、 ( 4 v i , 4 w i ) (4v_i, 4w_i) (4vi?,4wi?) ( 5 v i , 5 w i ) (5v_i, 5w_i) (5vi?,5wi?)


3. 代碼實(shí)現(xiàn)

#include <bits/stdc++.h>

using namespace std;

//逐一枚舉到最大是 N * logN
const int N = 12010, M = 2010;

int n, m;
int v[N], w[N], f[M];

int main()
{
    cin >> n >> m;
    
    int cnt = 0; //分組的類別
    for (int i = 1; i <= n; i ++)
    {
        int a, b, s;
        cin >> a >> b >> s;
        
        int k = 1; //組別里面的個(gè)數(shù)
        while (k <= s)
        {
            cnt ++; //組別先增加
            v[cnt] = a * k; //整體體積
            w[cnt] = b * k; //整體價(jià)值
            s -= k; //物品的個(gè)數(shù)要減少k個(gè)
            k *= 2; //組別里面的個(gè)數(shù)增加
        }
        
        //剩余的一組
        if (s >= 0)
        {
            cnt ++;
            v[cnt] = a * s;
            w[cnt] = b * s;
        }
    }
    
    n = cnt; //枚舉次數(shù)由個(gè)數(shù)變成組別數(shù)
    
    //01背包一維優(yōu)化
    for (int i = 1; i <= n; i ++)
        for (int j = m; j >= v[i]; j --)
            f[j] = max(f[j], f[j - v[i]] + w[i]);
    
    cout << f[m] << endl;
    
    return 0;
}

五、分組背包問題

1. 題目描述

有 N 組物品和一個(gè)容量是 V 的背包。

每組物品有若干個(gè),同一組內(nèi)的物品最多只能選一個(gè)。
每件物品的體積是 v i j v_{ij} vij?,價(jià)值是 w i j w_{ij} wij?,其中 i i i 是組號(hào), j j j 是組內(nèi)編號(hào)。

求解將哪些物品裝入背包,可使物品總體積不超過背包容量,且總價(jià)值最大。

輸出最大價(jià)值。

輸入格式

第一行有兩個(gè)整數(shù) N,V,用空格隔開,分別表示物品組數(shù)和背包容量。

接下來有 N 組數(shù)據(jù):

  • 每組數(shù)據(jù)第一行有一個(gè)整數(shù) S i S_i Si?,表示第 i i i 個(gè)物品組的物品數(shù)量;
  • 每組數(shù)據(jù)接下來有 S i S_i Si? 行,每行有兩個(gè)整數(shù) v i j , w i j v_{ij},w_{ij} vij?,wij?,用空格隔開,分別表示第 i i i 個(gè)物品組的第 j j j 個(gè)物品的體積和價(jià)值;

輸出格式

輸出一個(gè)整數(shù),表示最大價(jià)值。

數(shù)據(jù)范圍

0 < N , V ≤ 100 0<N,V≤100 0<N,V100
0 < S i ≤ 100 0<S_i≤100 0<Si?100
$0< v i j , w i j v_{ij},w_{ij} vij?,wij?≤100$

輸入樣例

3 5
2
1 2
2 4
1
3 4
1
4 5

輸出樣例:

8

2. 思路分析

最大價(jià)值應(yīng)該是物品組 i i i 和背包容量 j j j 的函數(shù),用 f[i][j] 表示前 i i i 組物品,能放入容量為 j j j 的背包的最大價(jià)值。

樸素算法應(yīng)該是循環(huán)物品組,循環(huán)背包容量,對(duì)第 i i i 組物品,容量為 j j j 的背包,有 s + 1 s + 1 s+1 種選法,

max(f[i - 1][j], f[i - 1][j - v 1 v_1 v1?] + w 1 w_1 w1?, f[i - 1][j - v 2 v_2 v2?] + w 2 w_2 w2?,…,f[i - 1][j - v 5 v_5 v5?] + w 5 w_5 w5?)

代碼如下:

	// 背包問題,樸素算法
    for (int i = 1; i <= n; i ++) //物品
        for (int j = 1; j <= m; j ++) //體積
            for (int k = 0; k < s[i]; k ++) //決策
                if (v[i][k] <= j)
                    f[i][j] = max(f[i][j], f[i - 1][j - v[i][k]] + w[i][k]);
    
    cout << f[n][m] << endl;

可以優(yōu)化為一維數(shù)組:

    for (int i = 1; i <= n; i ++) //物品
        for (int j = m; j >= 0; j --) //體積
            for (int k = 0; k < s[i]; k ++) //決策
                if (v[i][k] <= j)
                    f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);
    
    cout << f[m] << endl;

3. 代碼實(shí)現(xiàn)

#include <bits/stdc++.h>

using namespace std;

const int N = 110;

int n, m;
int v[N][N], w[N][N], s[N];
int f[N];

int main()
{
    cin >> n >> m;
    
    for (int i = 1; i <= n; i ++)
    {
        cin >> s[i];
        for (int j = 0; j < s[i]; j ++)
            cin >> v[i][j] >> w[i][j];
    }
    
    for (int i = 1; i <= n; i ++) //物品
        for (int j = m; j >= 0; j --) //體積
            for (int k = 0; k < s[i]; k ++) //決策
                if (v[i][k] <= j)
                    f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);
    
    cout << f[m] << endl;
    
    return 0;
}

創(chuàng)作不易,如果有幫助到你,請(qǐng)給文章點(diǎn)個(gè)贊和收藏,讓更多的人看到!??!
關(guān)注博主不迷路,內(nèi)容持續(xù)更新中。文章來源地址http://www.zghlxwxcb.cn/news/detail-420805.html

到了這里,關(guān)于算法基礎(chǔ)復(fù)盤筆記Day09【動(dòng)態(tài)規(guī)劃】—— 背包問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • acwing算法基礎(chǔ)之動(dòng)態(tài)規(guī)劃--背包問題

    (零) 背包問題描述:有 N N N 個(gè)物品,每個(gè)物品的體積是 v i v_i v i ? ,價(jià)值是 w i w_i w i ? ,現(xiàn)有容量是 V V V 的背包,求這個(gè)背包能裝下的物品的最大價(jià)值。 01背包問題:每個(gè)物品只有1個(gè)。 完全背包問題:每個(gè)物品有無窮多個(gè)。 多重背包問題:第 i i i 個(gè)物品有 s i s_i s

    2024年02月05日
    瀏覽(19)
  • 力扣算法刷題Day42|動(dòng)態(tài)規(guī)劃:01背包問題 分割等和子集

    力扣題目:01背包問題(二維數(shù)組) 刷題時(shí)長:參考題解 解題方法:動(dòng)態(tài)規(guī)劃 +?二維dp數(shù)組 復(fù)雜度分析 時(shí)間 空間 問題總結(jié) 理解遞推公式困難 本題收獲 動(dòng)規(guī)思路:兩層for循環(huán),第一層i遍歷物品,第二層j枚舉背包容量以內(nèi)所有值 確定dp數(shù)組及下標(biāo)的含義:dp[i][j] 表示從下標(biāo)

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

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

    2024年02月13日
    瀏覽(28)
  • Python 算法基礎(chǔ)篇:背包問題的動(dòng)態(tài)規(guī)劃解法

    背包問題是計(jì)算機(jī)科學(xué)中一個(gè)重要的組合優(yōu)化問題,動(dòng)態(tài)規(guī)劃是解決該問題的高效算法技術(shù)。本篇博客將重點(diǎn)介紹背包問題的動(dòng)態(tài)規(guī)劃解法,包括狀

    2024年02月16日
    瀏覽(26)
  • 動(dòng)態(tài)規(guī)劃day05(背包問題)

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

    2024年01月17日
    瀏覽(16)
  • 動(dòng)態(tài)規(guī)劃day04(01背包問題)

    01背包問題(二維數(shù)組和滾動(dòng)數(shù)組) 本題力扣上沒有原題,大家可以去卡碼網(wǎng)第46題?(opens new window)去練習(xí),題意是一樣的。 《代碼隨想錄》算法視頻公開課?(opens new window):帶你學(xué)透0-1背包問題!?(opens new window),相信結(jié)合視頻再看本篇題解,更有助于大家對(duì)本題的理解 。 這周

    2024年01月18日
    瀏覽(20)
  • day48算法訓(xùn)練|動(dòng)態(tài)規(guī)劃part09

    day48算法訓(xùn)練|動(dòng)態(tài)規(guī)劃part09

    1. dp數(shù)組(dp table)以及下標(biāo)的含義 dp[i]:考慮下標(biāo)i(包括i)以內(nèi)的房屋,最多可以偷竊的金額為dp[i] 。 2.遞推公式 決定dp[i]的因素就是第i房間偷還是不偷。 如果偷第i房間,那么dp[i] = dp[i - 2] + nums[i] ,即:第i-1房一定是不考慮的,找出 下標(biāo)i-2(包括i-2)以內(nèi)的房屋,最多

    2024年01月16日
    瀏覽(22)
  • Day 42 算法記錄|動(dòng)態(tài)規(guī)劃 09 (打家劫舍)

    Day 42 算法記錄|動(dòng)態(tài)規(guī)劃 09 (打家劫舍)

    1.dp[i]:考慮下標(biāo)i(包括i)以內(nèi)的房屋,最多可以偷竊的金額為dp[i]。 2.dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]); 3.初始化,dp[0] 和 dp[1],dp[0] 一定是 nums[0],dp[1] = max(nums[0], nums[1]); 3.遍歷順序,dp[i] 是根據(jù)dp[i - 2] 和 dp[i - 1] 推導(dǎo)出來的,那么一定是從前到后遍歷! 進(jìn)一步對(duì)滾動(dòng)數(shù)組

    2024年02月15日
    瀏覽(24)
  • Leetcoder Day39| 動(dòng)態(tài)規(guī)劃part06 完全背包問題

    Leetcoder Day39| 動(dòng)態(tài)規(guī)劃part06 完全背包問題

    有N件物品和一個(gè)最多能背重量為W的背包。第i件物品的重量是weight[i],得到的價(jià)值是value[i] 。 每件物品都有無限個(gè)(也就是可以放入背包多次) ,求解將哪些物品裝入背包里物品價(jià)值總和最大。 示例: 背包最大重量為4。 物品為: 重量 價(jià)值 物品0 1 15 物品1 3 20 物品2 4 30 每

    2024年03月25日
    瀏覽(24)
  • 算法學(xué)習(xí)筆記(動(dòng)態(tài)規(guī)劃——01背包)

    先來聊聊動(dòng)態(tài)規(guī)劃,動(dòng)態(tài)規(guī)劃是分治法的一種體現(xiàn),把一個(gè)問題分解成若干個(gè)子集,通過當(dāng)前狀態(tài),經(jīng)過操作得到下一個(gè)狀態(tài),最后得到最優(yōu)問題解的一種方法。 步驟: 設(shè)定狀態(tài),保存狀態(tài) 根據(jù)狀態(tài)設(shè)定轉(zhuǎn)移方程 確定邊界 其中的01背包解決的是關(guān)于選擇的動(dòng)態(tài)規(guī)劃問題,

    2024年03月25日
    瀏覽(25)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包