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

算法修煉之筑基篇——筑基一層中期(解決01背包,完全背包,多重背包)

這篇具有很好參考價值的文章主要介紹了算法修煉之筑基篇——筑基一層中期(解決01背包,完全背包,多重背包)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

?博主:命運之光??????

??專欄:算法修煉之練氣篇?????

??專欄:算法修煉之筑基篇

?博主的其他文章:點擊進(jìn)入博主的主頁??????

前言:學(xué)習(xí)了算法修煉之練氣篇想必各位蒟蒻們的基礎(chǔ)已經(jīng)非常的扎實了,下來我們進(jìn)階到算法修煉之筑基篇的學(xué)習(xí)。筑基期和練氣期難度可謂是天差地別,懂得都懂,題目難度相比起練氣期的題目難度提升很多,所以要是各位蒟蒻小伙伴們看不懂筑基期的題目可以在練氣期多積累積累,練氣期的題目也會不斷更新,大家一定要把基礎(chǔ)打牢固了再來看筑基期的題目哈,這樣子也可以提高大家的學(xué)習(xí)效率,一舉兩得,加油(●'?'●)????

算法修煉之筑基篇——筑基一層中期(解決01背包,完全背包,多重背包)

目錄

?詳解文字版(01背包,完全背包,多重背包)

??01背包問題

???完全背包問題

??多重背包問題

?01背包問題(經(jīng)典)

??小明的背包1

??解法一:二維dp數(shù)組

??解法二:一維dp數(shù)組

?完全背包問題(經(jīng)典)

??小明的背包2

??一維dp數(shù)組

??一維dp數(shù)組關(guān)鍵步驟(記憶)

??01背包和完全背包兩個對比(重要)

??總結(jié)就一個公式(超級無敵重要)

????01背包總結(jié)

????完全背包總結(jié)

?多重背包問題(經(jīng)典)

??小明的背包3

??重要步驟


?詳解文字版(01背包,完全背包,多重背包)

光看文字我感覺,很難理解背包問題,關(guān)鍵還是要看看底下的經(jīng)典例題,看完差不多就可以了,問題不好理解,大家加油哈(●'?'●)

背包問題的理解和解法。這三種問題分別是:

  • 01背包問題:每種物品只能選擇一次,求最大價值。
  • 完全背包問題:每種物品可以選擇無限次,求最大價值。
  • 多重背包問題:每種物品有一個選擇上限,求最大價值。

這三種問題都可以用動態(tài)規(guī)劃的思想來解決,關(guān)鍵是找到狀態(tài)轉(zhuǎn)移方程。下面我就分別介紹一下這三種問題的思路和代碼實現(xiàn)。(看不懂的話可以直接跳到例題,看例題我感覺就能直接理解,不用文字這么的啰嗦哈哈啊哈??)

??01背包問題

01背包問題是所有背包問題的基礎(chǔ),之后的問題都可以在此基礎(chǔ)之上變化,所以一定要理解清楚。尤其是對待不同問題,找出狀態(tài)轉(zhuǎn)移方程是解題的關(guān)鍵。

假設(shè)有N件物品和一個容量為V的背包。第i件物品的體積是v[i],價值是w[i]。我們用f[i][j]表示前i件物品恰好放入一個容量為j的背包中的最大價值。那么我們可以得到如下的狀態(tài)轉(zhuǎn)移方程:

f[i][j] = max(f[i-1][j], f[i-1][j-v[i]] + w[i])

這個方程的意思是,對于第i件物品,我們有兩種選擇:放或者不放。如果不放,那么前i件物品的最大價值就等于前i-1件物品的最大價值;如果放,那么前i件物品的最大價值就等于前i-1件物品在剩余空間j-v[i]中的最大價值加上第i件物品的價值。我們?nèi)∵@兩種情況中較大的一個作為f[i][j]的值。

根據(jù)這個方程,我們可以用二維數(shù)組來存儲f[i][j]的值,并從小到大遍歷所有可能的狀態(tài)。最終答案就是f[N][V]。

??下面是用C++實現(xiàn)的代碼:

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 1001; // 物品數(shù)量和背包容量的上限
int f[N][N]; // 存儲狀態(tài)轉(zhuǎn)移方程的結(jié)果
int v[N]; // 存儲每件物品的體積
int w[N]; // 存儲每件物品的價值

int main() {
int n, V; // 物品數(shù)量和背包容量
cin >> n >> V;
for (int i = 1; i <= n; i++) {
cin >> v[i] >> w[i]; // 輸入每件物品的體積和價值
}
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= V; j++) {
f[i][j] = f[i-1][j]; // 不放第i件物品
if (j >= v[i]) { // 如果能放得下第i件物品
f[i][j] = max(f[i][j], f[i-1][j-v[i]] + w[i]); // 取放和不放中較大的一個
}
}
}
cout << f[n][V] << endl; // 輸出最大價值
return 0;
}

???完全背包問題

完全背包問題與01背包問題非常相似,只是每種物品可以選擇無限次而已。這樣一來,我們的狀態(tài)轉(zhuǎn)移方程就有所變化:

f[i][j] = max(f[i-1][j], f[i][j-v[i]] + w[i])

這個方程的意思是,對于第i件物品,我們有兩種選擇:放或者不放。如果不放,那么前i件物品的最大價值就等于前i-1件物品的最大價值;如果放,那么前i件物品的最大價值就等于當(dāng)前物品在剩余空間j-v[i]中的最大價值加上第i件物品的價值。注意這里和01背包問題的區(qū)別,因為可以放多次,所以是f[i][j-v[i]]而不是f[i-1][j-v[i]]。

根據(jù)這個方程,我們?nèi)匀豢梢杂枚S數(shù)組來存儲f[i][j]的值,并從小到大遍歷所有可能的狀態(tài)。最終答案仍然是f[N][V]。

??下面是用C++實現(xiàn)的代碼:

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 1001; // 物品數(shù)量和背包容量的上限
int f[N][N]; // 存儲狀態(tài)轉(zhuǎn)移方程的結(jié)果
int v[N]; // 存儲每件物品的體積
int w[N]; // 存儲每件物品的價值

int main() {
int n, V; // 物品數(shù)量和背包容量
cin >> n >> V;
for (int i = 1; i <= n; i++) {
cin >> v[i] >> w[i]; // 輸入每件物品的體積和價值
}
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= V; j++) {
f[i][j] = f[i-1][j]; // 不放第i件物品
if (j >= v[i]) { // 如果能放得下第i件物品
f[i][j] = max(f[i][j], f[i][j-v[i]] + w[i]); // 取放和不放中較大的一個
}
}
}
cout << f[n][V] << endl; // 輸出最大價值
return 0;
}

??多重背包問題

多重背包問題的描述是這樣的:有n種物品和一個容量為m的背包,每種物品有一定的重量w[i]和價值v[i],還有數(shù)量限制num[i],即每種物品最多只能放num[i]個。問如何選擇放入背包的物品,使得背包內(nèi)物品的總價值最大,且不超過背包的容量。??

這個問題看起來很復(fù)雜,但其實我們可以用一些技巧來簡化它。首先,我們可以把每種物品看成是若干個01背包問題中的物品,即把第i種物品分成num[i]個單獨的物品,每個物品的重量和價值都是w[i]和v[i]。這樣我們就把多重背包問題轉(zhuǎn)化成了一個01背包問題。??

然后,我們可以用一個二維數(shù)組dp[i][j]來表示從前i個物品中選擇若干個放入容量為j的背包時能獲得的最大價值。我們可以用一個循環(huán)來遍歷所有的物品,對于每個物品,我們又用一個循環(huán)來遍歷所有可能的背包容量,然后根據(jù)放或不放這個物品來更新dp[i][j]的值。具體來說,如果不放這個物品,那么dp[i][j]就等于dp[i-1][j],即前i-1個物品放入容量為j的背包時能獲得的最大價值;如果放這個物品,那么dp[i][j]就等于dp[i-1][j-w[i]]+v[i],即前i-1個物品放入容量為j-w[i]的背包時能獲得的最大價值加上當(dāng)前物品的價值。我們要在這兩種情況中取較大的那個作為dp[i][j]的值。??

最后,我們可以輸出dp[n][m]作為最終答案,即從n種物品中選擇若干個放入容量為m的背包時能獲得的最大價值。這就是多重背包問題的解法。??

?01背包問題(經(jīng)典)

??小明的背包1

算法修煉之筑基篇——筑基一層中期(解決01背包,完全背包,多重背包)

??解法一:二維dp數(shù)組

#include<bits/stdc++.h>
using namespace std;
int dp[1005][1005],w[1005],v[1005];
int main()
{
	//經(jīng)典的01背包問題需要記憶 
	int n,m;
	int i,j;
	cin>>n>>m;
	for(i=1;i<=n;i++)
	{
		cin>>w[i]>>v[i];
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			if(j<w[i])
			{
				dp[i][j]=dp[i-1][j];//記憶	
			}
			else
			{
				dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);//記憶 
			}	
		}
	 } 	 
	cout<<dp[n][m];	
	return 0;
}

??解法二:一維dp數(shù)組

#include<bits/stdc++.h>
using namespace std;
int dp[1005],w[1005],v[1005];
int main()
{
	//經(jīng)典的01背包問題需要記憶 
	int n,m;
	int i,j;
	cin>>n>>m;
	for(i=1;i<=n;i++)
	{
		cin>>w[i]>>v[i];
	}
	for(i=1;i<=n;i++)
	{
		for(j=m;j>=1;j--)//--j和j--不影響,01背包是逆序 
		{
			if(j>w[i])
			{
				dp[j]=max(dp[j-1],dp[j-w[i]]+v[i]);
			}	
		}
	 } 	 
	cout<<dp[m];	
	return 0;
}

??用這個dp[j]=max(dp[j],dp[j-w[i]]+v[i])

#include<bits/stdc++.h>
using namespace std;
int dp[1005],w[1005],v[1005];
int main()
{
	//經(jīng)典的01背包問題需要記憶 
	int n,m;
	int i,j;
	cin>>n>>m;
	for(i=1;i<=n;i++)
	{
		cin>>w[i]>>v[i];
	}
	for(i=1;i<=n;i++)
	{
		for(j=m;j>=1;j--)//--j和j--不影響,01背包是逆序 
		{
      		if(j>=w[i])
				dp[j]=max(dp[j],dp[j-w[i]]+v[i]);	
		}
	 } 	 
	cout<<dp[m];	
	return 0;
}

下面是需要記憶知識點(01背包問題中的推到公式需要記憶)

??二維dp數(shù)組

	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			if(j<w[i])
			{
				dp[i][j]=dp[i-1][j];//記憶	
			}
			else
			{
				dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);//記憶 
			}	
		}
	 }

??一維dp數(shù)組(重要)

for(i=1;i<=n;i++)
{
    for(j=m;j>=1;j--)//--j和j--不影響,01背包是逆序 
    {
        if(j>=w[i])
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);	
    }
 } 

算法修煉之筑基篇——筑基一層中期(解決01背包,完全背包,多重背包)

?完全背包問題(經(jīng)典)

??小明的背包2

算法修煉之筑基篇——筑基一層中期(解決01背包,完全背包,多重背包)

??一維dp數(shù)組

#include<bits/stdc++.h>
using namespace std;
int dp[1005],w[1005],v[1005];
int main()
{
	//經(jīng)典的完全背包問題需要記憶 
	int n,m;
	int i,j;
	cin>>n>>m;
	for(i=1;i<=n;i++)
	{
		cin>>w[i]>>v[i];
	}
	for(i=1;i<=n;i++)
	{
		for(j=w[i];j<=m;j++)
		{
			dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
		}
	 } 	 
	cout<<dp[m];	
	return 0;
}

??一維dp數(shù)組關(guān)鍵步驟(記憶)

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

算法修煉之筑基篇——筑基一層中期(解決01背包,完全背包,多重背包)

??01背包和完全背包兩個對比(重要)

算法修煉之筑基篇——筑基一層中期(解決01背包,完全背包,多重背包)

算法修煉之筑基篇——筑基一層中期(解決01背包,完全背包,多重背包)

??總結(jié)就一個公式(超級無敵重要)

dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

其中01背包是逆向推到,完全背包是正向推到

????01背包總結(jié)

for(i=1;i<=n;i++)
{
    for(j=m;j>=1;j--)//--j和j--不影響,01背包是逆序 
    {
        if(j>=w[i])
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);	
    }
 } 

????完全背包總結(jié)

for(i=1;i<=n;i++)
{
    for(j=w[i];j<=m;j++)//重要點,j=w[i];j<=m;j++
    {
        dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    }
 } 

?多重背包問題(經(jīng)典)

理解了上面的01背包問題和多重背包問題就很好理解多重背包問題了

??小明的背包3

算法修煉之筑基篇——筑基一層中期(解決01背包,完全背包,多重背包)

#include<bits/stdc++.h>
using namespace std;
int dp[205],w[205],vi[205],s[205];
int main()
{
	//經(jīng)典的多重背包問題 
	int n,v;
	int i,j;
	cin>>n>>v;
	for(i=1;i<=n;i++)
	{
		cin>>w[i]>>vi[i]>>s[i];
	}
	
	for(i=1;i<=n;i++)
	{
		for(j=v;j>=1;j--)
		{
			for(int k=0;k<=s[i]&&j>=k*w[i];++k)
			{
				//從01背包的狀態(tài)轉(zhuǎn)移方程式,去增加i個物品拿k個循環(huán) 
				dp[j]=max(dp[j],dp[j-k*w[i]]+k*vi[i]);
			}
		}
	}
	cout<<dp[v]; 
	return 0;
}

??重要步驟

??就是在01背包的基礎(chǔ)上加上K循環(huán)的約束條件dp[j]=max(dp[j],dp[j-k*w[i]]+k*vi[i])文章來源地址http://www.zghlxwxcb.cn/news/detail-478089.html

for(i=1;i<=n;i++)
	{
		for(j=v;j>=1;j--)//01背包的基礎(chǔ)上他這個也是逆向的
		{
			for(int k=0;k<=s[i]&&j>=k*w[i];++k)
			{
				//從01背包的狀態(tài)轉(zhuǎn)移方程式,去增加i個物品拿k個循環(huán) 
				dp[j]=max(dp[j],dp[j-k*w[i]]+k*vi[i]);
			}
		}
	}

到了這里,關(guān)于算法修煉之筑基篇——筑基一層中期(解決01背包,完全背包,多重背包)的文章就介紹完了。如果您還想了解更多內(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ù)器費用

相關(guān)文章

  • 【藍(lán)橋杯-筑基篇】動態(tài)規(guī)劃

    【藍(lán)橋杯-筑基篇】動態(tài)規(guī)劃

    ??系列專欄:藍(lán)橋杯 ??個人主頁:個人主頁 目錄 1.最大連續(xù)子段和 2.LCS 最大公共子序列 3.LIS 最長上升子序列 4.數(shù)塔 5.最大子矩陣和 6.背包問題 ①01背包問題 ②完全背包 這段代碼是一個求最大子數(shù)組和的算法,使用的是動態(tài)規(guī)劃的思想。下面是代碼的解釋: 首先定義了一個

    2023年04月24日
    瀏覽(22)
  • 【藍(lán)橋杯-筑基篇】搜索

    【藍(lán)橋杯-筑基篇】搜索

    ??系列專欄:藍(lán)橋杯 ??個人主頁:個人主頁 目錄 遞歸樹 1.遞歸構(gòu)建二進(jìn)制串? 2.全排列的 DFS 解法 3.全排列的 BFS 解法 4.數(shù)的劃分法 5.圖書推薦 遞歸樹 遞歸樹是一種用于分析遞歸算法時間復(fù)雜度的工具。它可以將遞歸算法的執(zhí)行過程可視化,從而更好地理解算法的時間復(fù)雜度

    2024年01月16日
    瀏覽(19)
  • 【藍(lán)橋杯-筑基篇】貪心

    【藍(lán)橋杯-筑基篇】貪心

    ??系列專欄:藍(lán)橋杯 ??個人主頁:個人主頁 目錄 1.找零問題 ①暴力枚舉 ②貪心 2.人性總是貪婪的 3.堆果子 4.圖書推薦 有幣種 1 、 2 、 4 、 5 、 10 若干張,找零 n 元,輸出找零方案。 ①暴力枚舉 這是一個找零問題,我們需要找到一種方案,使得用給定的硬幣找零時,所需的

    2024年01月18日
    瀏覽(19)
  • 百日筑基篇——python爬蟲學(xué)習(xí)(一)

    百日筑基篇——python爬蟲學(xué)習(xí)(一)

    百日筑基篇——python爬蟲學(xué)習(xí)(一) 隨著學(xué)習(xí)的深入,有關(guān)從各種不同的數(shù)據(jù)庫中以及互聯(lián)網(wǎng)上的海量信息,如何有選擇性的爬取我們所需的數(shù)據(jù)以方便我們的數(shù)據(jù)分析工作,爬蟲的學(xué)習(xí)是必要的。 Python爬蟲是指使用Python編程語言編寫的程序,通過模擬瀏覽器行為從網(wǎng)頁中

    2024年02月13日
    瀏覽(21)
  • MySQL筑基篇之增刪改查

    ?作者簡介:C/C++領(lǐng)域新星創(chuàng)作者,為C++和java奮斗中 ?個人社區(qū):微涼秋意社區(qū) ??系列專欄:MySql一點通 ??推薦一款模擬面試、刷題神器??注冊免費刷題 ??前言 本文將承接前兩篇MySQL專欄的博文,講解數(shù)據(jù)庫的 增刪改查 操作,這里的查詢確切的說應(yīng)該是初級的查詢,不

    2024年02月12日
    瀏覽(20)
  • C++修煉之筑基期第三層——拷貝構(gòu)造函數(shù)

    C++修煉之筑基期第三層——拷貝構(gòu)造函數(shù)

    ??作者簡介: 花想云 ,在讀本科生一枚,致力于 C/C++、Linux 學(xué)習(xí)。 ?? 本文收錄于 C++系列 ,本專欄主要內(nèi)容為 C++ 初階、C++ 進(jìn)階、STL 詳解等,專為大學(xué)生打造全套 C++ 學(xué)習(xí)教程,持續(xù)更新! ?? 相關(guān)專欄推薦: C語言初階系列 、 C語言進(jìn)階系列 、 數(shù)據(jù)結(jié)構(gòu)與算法 本章主要

    2023年04月09日
    瀏覽(25)
  • C++修煉之筑基期第四層 ——透過日期類看運算符重載 | 賦值運算符重載 | 取地址操作符重載

    C++修煉之筑基期第四層 ——透過日期類看運算符重載 | 賦值運算符重載 | 取地址操作符重載

    ??作者簡介: 花想云 ,在讀本科生一枚,致力于 C/C++、Linux 學(xué)習(xí)。 ?? 本文收錄于 C++系列 ,本專欄主要內(nèi)容為 C++ 初階、C++ 進(jìn)階、STL 詳解等,專為大學(xué)生打造全套 C++ 學(xué)習(xí)教程,持續(xù)更新! ?? 相關(guān)專欄推薦: C語言初階系列 、 C語言進(jìn)階系列 、 數(shù)據(jù)結(jié)構(gòu)與算法 本章主要

    2023年04月09日
    瀏覽(21)
  • 音頻筑基:算法時延分析

    音頻算法中,經(jīng)常遇到時延分析的問題,剛開始接觸大多都比較迷惑,這里將自己對時延的學(xué)習(xí)思考梳理總結(jié)于此。 音頻領(lǐng)域中,時延(delay/latency)主要指聲音從源端發(fā)出,經(jīng)鏈路傳輸,再到對端接收到聲音,所經(jīng)過的總時間延遲。一般人耳無法感知的藍(lán)牙段鏈路時延是25-30

    2024年01月17日
    瀏覽(19)
  • 算法修煉之練氣篇——練氣七層

    算法修煉之練氣篇——練氣七層

    博主:命運之光 專欄:算法修煉之練氣篇 前言:每天練習(xí)五道題,煉氣篇大概會練習(xí)200道題左右,題目有C語言網(wǎng)上的題,也有洛谷上面的題,題目簡單適合新手入門。(代碼都是命運之光自己寫的,練完這200多道題就考了今年第十四屆的B組藍(lán)橋杯C/C++獲得了省一,后面還會

    2024年02月05日
    瀏覽(14)
  • 算法修煉之練氣篇——練氣五層

    算法修煉之練氣篇——練氣五層

    博主:命運之光 專欄:算法修煉之練氣篇 前言:每天練習(xí)五道題,煉氣篇大概會練習(xí)200道題左右,題目有C語言網(wǎng)上的題,也有洛谷上面的題,題目簡單適合新手入門。(代碼都是命運之光自己寫的,練完這200多道題就考了今年第十四屆的B組藍(lán)橋杯C/C++獲得了省一,后面還會

    2024年02月05日
    瀏覽(11)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包