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

算法競(jìng)賽必考算法——?jiǎng)討B(tài)規(guī)劃(01背包和完全背包)

這篇具有很好參考價(jià)值的文章主要介紹了算法競(jìng)賽必考算法——?jiǎng)討B(tài)規(guī)劃(01背包和完全背包)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

動(dòng)態(tài)規(guī)劃(一)

背包問題算法考試,算法專題,算法,動(dòng)態(tài)規(guī)劃,c++,藍(lán)橋杯,數(shù)據(jù)結(jié)構(gòu)

背包問題算法考試,算法專題,算法,動(dòng)態(tài)規(guī)劃,c++,藍(lán)橋杯,數(shù)據(jù)結(jié)構(gòu)

1.01背包問題

1.1題目介紹

背包問題算法考試,算法專題,算法,動(dòng)態(tài)規(guī)劃,c++,藍(lán)橋杯,數(shù)據(jù)結(jié)構(gòu)

1.2思路一介紹(二維數(shù)組)

背包問題算法考試,算法專題,算法,動(dòng)態(tài)規(guī)劃,c++,藍(lán)橋杯,數(shù)據(jù)結(jié)構(gòu)

代碼如下:

#include<iostream>
#include<algorithm>
using namespace std;
 const int N=1010;
 int v[N],w[N]; //v[N]是物品體積 w[N]是物品的價(jià)值
 int f[N][N]; //f[i][j]在體積不超j的前提下,從i個(gè)物品中選擇最大值
 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++)
         {
             f[i][j]=f[i-1][j];
             if(j>=v[i])//如果我們的背包容量j大于第i個(gè)物品的體積,我們?cè)谶M(jìn)行決策是否加入第i個(gè)物品
             f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
         }
     }
     cout<<f[n][m]<<endl;
     return 0;
 }

1.3思路二介紹(一維數(shù)組) 空間優(yōu)化

??為什么可以使用一維數(shù)組?

??我們先來看一看01背包問題的狀態(tài)轉(zhuǎn)移方程,我們可以發(fā)現(xiàn) f[i]只用到了f[i-1],其他的是沒有用到的,我們可以用滾動(dòng)數(shù)組來做。
??還有一個(gè)原因就是我們?cè)谟?jì)算f[i] [j]的時(shí)候我們只用到了f[i-1] [j]和f[i-1] [j-v[i]],其中j和j-v[i]都是小于等于j的,在j的同一側(cè),所以我們綜合以上兩點(diǎn)原因就可以將二維優(yōu)化到一維,即完成空間優(yōu)化。

背包問題算法考試,算法專題,算法,動(dòng)態(tài)規(guī)劃,c++,藍(lán)橋杯,數(shù)據(jù)結(jié)構(gòu)

我們先來將二維和優(yōu)化后的一維在關(guān)鍵算法代碼上進(jìn)行一下對(duì)比:

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)枚舉的背包容量 >= v[i] 時(shí)才會(huì)更新狀態(tài),因此我們可以修改循環(huán)終止條件進(jìn)一步優(yōu)化。

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

背包問題算法考試,算法專題,算法,動(dòng)態(tài)規(guī)劃,c++,藍(lán)橋杯,數(shù)據(jù)結(jié)構(gòu)

#include <iostream>
#include <algorithm>

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.4思路三介紹(輸入數(shù)據(jù)優(yōu)化)

??我們注意到在處理數(shù)據(jù)時(shí),我們是一個(gè)物品一個(gè)物品,一個(gè)一個(gè)體積的枚舉。因此我們可以不必開兩個(gè)數(shù)組記錄體積和價(jià)值,而是邊輸入邊處理。

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1005;
int f[MAXN];  // 

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;
}

背包問題算法考試,算法專題,算法,動(dòng)態(tài)規(guī)劃,c++,藍(lán)橋杯,數(shù)據(jù)結(jié)構(gòu)

2.完全背包問題

2.1題目描述:

背包問題算法考試,算法專題,算法,動(dòng)態(tài)規(guī)劃,c++,藍(lán)橋杯,數(shù)據(jù)結(jié)構(gòu)
背包問題算法考試,算法專題,算法,動(dòng)態(tài)規(guī)劃,c++,藍(lán)橋杯,數(shù)據(jù)結(jié)構(gòu)

2.2思路一(樸素算法)

#include<iostream>
using namespace std;
const int N=1010;
int f[N][N];
int n,m;
int v[N],w[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=0;j<=m;j++)
        {
            for(int k=0;k*v[i]<=j;k++)
            {
                f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);
            }
        }
    }
    cout<<f[n][m]<<endl;
    return 0;
}

上述樸素算法和01背包問題的樸素算法非常相似,但是會(huì)超時(shí)。所以我們接下來就會(huì)對(duì)這個(gè)算法進(jìn)行優(yōu)化處理。

2.3思路二(將k優(yōu)化處理掉)

背包問題算法考試,算法專題,算法,動(dòng)態(tài)規(guī)劃,c++,藍(lán)橋杯,數(shù)據(jù)結(jié)構(gòu)

??我們先來分析一下狀態(tài)轉(zhuǎn)移方程,我們發(fā)現(xiàn)方程一和方程二有一定的聯(lián)系,我們先不看方程一紅色圈出來的部分,我們比較方程一黃色的部分和方程二的內(nèi)容,我們發(fā)現(xiàn)方程一就是比方程二每一項(xiàng)多了一個(gè)w,那么我們黃色圈出來的部分的最大值也就比方程二的最大值多w,那么我們其實(shí)就可以將方程一圈出來黃色的部分進(jìn)行等價(jià)替換,替換成紅色方框黃色字體的內(nèi)容,我們最終得出最下方的結(jié)論,其實(shí)我們要求得最大值之和兩個(gè)狀態(tài)有關(guān),比較它們的最大值即可。

我們發(fā)現(xiàn)好像最后的狀態(tài)轉(zhuǎn)移方程和k并沒有關(guān)系了,那么我們就干脆去掉k的那次循環(huán)

所以我們對(duì)核心代碼進(jìn)行了優(yōu)化:

for(int i = 1 ; i <=n ;i++)
for(int j = 0 ; j <=m ;j++)
{
    f[i][j] = f[i-1][j];//狀態(tài)一,即不取第i個(gè)物品
    if(j-v[i]>=0)//判斷是否可以加入第i個(gè)物品
        f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);//狀態(tài)二
}

完整代碼如下:

#include<iostream>
using namespace std;
const int N=1010;
int f[N][N];
int n,m;
int v[N],w[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=0;j<=m;j++)
        {
            f[i][j]=f[i-1][j];
            if(j>=v[i])
            {
                f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);
            }
        }
    }
    cout<<f[n][m]<<endl;
    return 0;
}

我們來比較一個(gè)完全背包的核心代碼和01背包核心代碼的區(qū)別:

//01背包問題核心優(yōu)化后代碼
for(int i=1;i<=n;i++)
{
	for(int j=m;j>=v[i];j--)
	{	f[i][j]=f[i-1][j];
		if(j>=v[i])
		{
			f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
		}
	}
}
//完全背包問題核心優(yōu)化后代碼
for(int i = 1 ; i <=n ;i++)
for(int j = 0 ; j <=m ;j++)
{
    f[i][j] = f[i-1][j];//狀態(tài)一,即不取第i個(gè)物品
    if(j-v[i]>=0)//判斷是否可以加入第i個(gè)物品
        f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);//狀態(tài)二
}

我們發(fā)現(xiàn)其實(shí)本質(zhì)也就是一句不同:注意i的下標(biāo)

背包問題算法考試,算法專題,算法,動(dòng)態(tài)規(guī)劃,c++,藍(lán)橋杯,數(shù)據(jù)結(jié)構(gòu)

??我們這個(gè)i的下標(biāo)是根據(jù)兩個(gè)不同的背包問題的狀態(tài)轉(zhuǎn)移方程得出來的,我們01背包問題因?yàn)橐褂玫趇-1層的數(shù)據(jù),所以我們枚舉j的時(shí)候只能從后往前枚舉,這樣做是因?yàn)閖-v[i]小于j,那么f[j-v[i]]的數(shù)據(jù)就會(huì)被改,那么我們使用的數(shù)據(jù)其實(shí)就是第i層的數(shù)據(jù)了,不滿足狀態(tài)轉(zhuǎn)移方程,所以我們要從后往前枚舉,但是完全背包問題使用的就是第i層的數(shù)據(jù),所以不存在從前往后枚舉就會(huì)在使用前數(shù)據(jù)就發(fā)生意外改變的這種情況,所以就在這個(gè)地方這兩個(gè)核心算法略有差別。

2.4思路三(優(yōu)化j的初始條件)

這個(gè)和01背包問題的優(yōu)化方法是一樣的,就不多贅述了。

核心代碼如下:

for(int i = 1 ; i<=n ;i++)
    for(int j = v[i] ; j<=m ;j++)//注意了,這里的j是從小到大枚舉,和01背包不一樣
    {
            f[j] = max(f[j],f[j-v[i]]+w[i]);
    }

完整代碼如下:

#include<iostream>
using namespace std;
const int N = 1010;
int f[N];
int v[N],w[N];
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 = v[i] ; j<=m ;j++)
    {
            f[j] = max(f[j],f[j-v[i]]+w[i]);
    }
    cout<<f[m]<<endl;
}

總結(jié)

??本篇博客主要涉及動(dòng)態(tài)規(guī)劃背包問題的01背包問題和完全背包問題,給大家分享了實(shí)現(xiàn)的思路和代碼模板,大家也可以看看yxc的背包九講,圖片轉(zhuǎn)載于yxc,希望對(duì)大家有所幫助,后面會(huì)持續(xù)更新~文章來源地址http://www.zghlxwxcb.cn/news/detail-784422.html

到了這里,關(guān)于算法競(jìng)賽必考算法——?jiǎng)討B(tài)規(guī)劃(01背包和完全背包)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(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)文章

  • 力扣刷題-動(dòng)態(tài)規(guī)劃算法3:完全背包問題

    力扣刷題-動(dòng)態(tài)規(guī)劃算法3:完全背包問題

    問題描述: 1)有N件物品和一個(gè)最多能背重量為W的背包。第i件物品的重量是weight[i],得到的價(jià)值是value[i] 。 2) 每件物品都有無限個(gè)(也就是可以放入背包多次) (比0-1背包多出的條件) 3) 求解將哪些物品裝入背包里物品價(jià)值總和最大。 求解步驟: 1)首先遍歷物品,然

    2023年04月13日
    瀏覽(137)
  • 代碼隨想錄 Day35 動(dòng)態(tài)規(guī)劃04 01背包問題和完全背包問題 LeetCode T416 分割等和子集

    代碼隨想錄 Day35 動(dòng)態(tài)規(guī)劃04 01背包問題和完全背包問題 LeetCode T416 分割等和子集

    說到背包問題大家都會(huì)想到使用動(dòng)規(guī)的方式來求解,那么為什么用動(dòng)規(guī)呢, dp數(shù)組代表什么呢 ? 初始化是什么 , 遍歷方式又是什么 ,這篇文章筆者將詳細(xì)講解背包問題的經(jīng)典例題0-1背包問題和完全背包問題的解題方式,希望能幫助到大家 有人一提到背包問題就只會(huì)使用動(dòng)態(tài)規(guī)劃來

    2024年02月06日
    瀏覽(124)
  • 動(dòng)態(tài)規(guī)劃——01背包和完全背包

    動(dòng)態(tài)規(guī)劃——01背包和完全背包

    目錄 01背包模型 題目? dp? ?滾動(dòng)數(shù)組優(yōu)化 第一問? 第二問? 擴(kuò)展 完全背包 題目? 動(dòng)態(tài)規(guī)劃?編輯? 滾動(dòng)數(shù)組優(yōu)化 ?關(guān)于-1的代碼層面優(yōu)化 ???? 背包就是有限制條件的組合問題 有一個(gè)背包能容納的體積是v,現(xiàn)在有n個(gè)物品,第i個(gè)物品的體積為vi,價(jià)值為wi。 (1)求這個(gè)背包

    2024年01月20日
    瀏覽(22)
  • 算法系列--動(dòng)態(tài)規(guī)劃--背包問題(1)--01背包介紹

    算法系列--動(dòng)態(tài)規(guī)劃--背包問題(1)--01背包介紹

    ??\\\"趁著年輕,做一些比較cool的事情\\\"?? 作者:Lvzi 文章主要內(nèi)容:算法系列–動(dòng)態(tài)規(guī)劃–背包問題(1)–01背包介紹 大家好,今天為大家?guī)淼氖?算法系列--動(dòng)態(tài)規(guī)劃--背包問題(1)--01背包介紹 背包問題是動(dòng)態(tài)規(guī)劃中經(jīng)典的一類問題,經(jīng)常在筆試面試中出現(xiàn),是非常 具有區(qū)分度 的題

    2024年04月16日
    瀏覽(93)
  • 算法篇——?jiǎng)討B(tài)規(guī)劃 完全和多重背包問題 (js版)

    算法篇——?jiǎng)討B(tài)規(guī)劃 完全和多重背包問題 (js版)

    01 背包 問題和 完全背包 問題的不同點(diǎn)在于,所有的物品只能 使用一次 ,判斷? 哪些物品? 裝進(jìn)背包里 物品價(jià)值和 最大;而 完全背包 問題中,所有物品都能 使用n次 ,判斷 哪個(gè)物品 裝 n 個(gè)進(jìn)去 物品價(jià)值和 最大。 01 背包的遞推公式是: 【當(dāng)然先遍歷物品還是背包的容量

    2024年02月08日
    瀏覽(29)
  • 算法學(xué)習(xí)17-動(dòng)態(tài)規(guī)劃01:背包問題

    算法學(xué)習(xí)17-動(dòng)態(tài)規(guī)劃01:背包問題

    提示:以下是本篇文章正文內(nèi)容: 提示:這里對(duì)文章進(jìn)行總結(jié): ??????

    2024年04月27日
    瀏覽(102)
  • 【筆記】動(dòng)態(tài)規(guī)劃(1)---01背包和完全背包

    集合:選法集合 屬性:最優(yōu)選擇 集合的劃分 狀態(tài)表示 集合:所有只考慮 第i個(gè)物品前的 且總體積不大于j的所有 選法 。 屬性:在所有集和中, 價(jià)值最大的選法 。 狀態(tài)計(jì)算 集合的劃分:總是在(第 i - 1個(gè)) 狀態(tài)最優(yōu)時(shí),計(jì)算 第 i 個(gè)狀態(tài)。 背包已經(jīng)最優(yōu),故對(duì)于任意容積

    2024年02月02日
    瀏覽(23)
  • 【動(dòng)態(tài)規(guī)劃】01背包問題——算法設(shè)計(jì)與分析

    【動(dòng)態(tài)規(guī)劃】01背包問題——算法設(shè)計(jì)與分析

    若超市允許顧客使用一個(gè)體積大小為13的背包,選擇一件或多件商品帶走,則如何選擇可以使得收益最高? 商品 價(jià)格 體積 啤酒 24 10 汽水 2 3 餅干 9 4 面包 10 5 牛奶 9 4 0-1 Knapsack Problem 輸入: quad - n n n 個(gè)商品組成集合 O O O ,每個(gè)商品有屬性價(jià)格 p i p_i p i ? 和體積 v i v_i v

    2024年02月04日
    瀏覽(85)
  • 算法分析與設(shè)計(jì)——?jiǎng)討B(tài)規(guī)劃求解01背包問題

    算法分析與設(shè)計(jì)——?jiǎng)討B(tài)規(guī)劃求解01背包問題

    假設(shè)有四個(gè)物品,如下圖,背包總?cè)萘繛?,求背包裝入哪些物品時(shí)累計(jì)的價(jià)值最多。 我們使用動(dòng)態(tài)規(guī)劃來解決這個(gè)問題,首先使用一個(gè)表格來模擬整個(gè)算法的過程。 表格中的信息表示 指定情況下能產(chǎn)生的最大價(jià)值 。例如, (4, 8)表示在背包容量為8的情況下,前四個(gè)物品的最

    2024年02月04日
    瀏覽(93)
  • 【Java實(shí)現(xiàn)】動(dòng)態(tài)規(guī)劃算法解決01背包問題

    【Java實(shí)現(xiàn)】動(dòng)態(tài)規(guī)劃算法解決01背包問題

    1、問題描述: 一個(gè)旅行者有一個(gè)最多能裝m公斤的背包,現(xiàn)在有n中物品,每件的重量分別是W1、W2、……、Wn,每件物品的價(jià)值分別為C1、C2、……、Cn, 需要將物品放入背包中,要怎么樣放才能保證背包中物品的總價(jià)值最大? 2、動(dòng)態(tài)規(guī)劃算法的概述 1)動(dòng)態(tài)規(guī)劃(Dynamic Progra

    2023年04月09日
    瀏覽(92)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包