日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

01背包,完全背包,多重背包,分组背包的使用条件以及代码模板

發布時間:2023/12/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 01背包,完全背包,多重背包,分组背包的使用条件以及代码模板 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背包問題算是動態規劃中的入門題目了,背包問題有很多種。背包九講中講的很清楚,我就不班門弄斧了,針對幾種比較常見的背包問題,闡述一下它的使用前提和代碼模板。
1.01背包問題

題目
有N 件物品和一個容量為V 的背包。第i ii件物品的費用是w[i] ,價值是v[i],求將哪些物品裝入背包可使價值總和最大。
這種基礎的01背包問題,一般有兩種代碼書寫規則,一種是二維數組,一種是一維數組。個人比較推薦一維數組,兩種數組,代碼書寫并不一樣。
一維數組代碼如下:

#include<bits/stdc++.h> using namespace std;const int maxx=1e3+100; int dp[maxx]; int w[maxx]; int v[maxx]; int n,m;int main() {scanf("%d%d",&n,&m);//m為總價值for(int i=0;i<n;i++) scanf("%d%d",&w[i],&v[i]);memset(dp,0,sizeof(dp));for(int i=0;i<n;i++){for(int j=m;j>=w[i];j--)//這個是倒序{dp[j]=max(dp[j],dp[j-w[i]]+v[i]);}} cout<<dp[m]<<endl;return 0;}

二維數組代碼如下:

#include<bits/stdc++.h> #define ll long long using namespace std;const int maxx=1e3+100; int w[maxx]; int v[maxx]; int dp[maxx][maxx]; int n,m;int main() {scanf("%d%d",&n,&m);for(int i=0;i<n;i++) scanf("%d%d",&w[i],&v[i]);memset(dp,0,sizeof(dp));for(int i=0;i<n;i++){for(int j=1;j<=m;j++)//這個是正序{if(w[i]<=j) dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);else dp[i][j]=dp[i-1][j];}}cout<<dp[n-1][m]<<endl;return 0; }

2.完全背包問題

題目
有N種物品和一個容量為V的背包,每種物品都有無限件可用。第i種物品的費用是w[i],價值是v[i]。求解將哪些物品裝入背包可使這些物品的費用總和不超過背包容量,且價值總和最大。

完全背包和01背包的區別是,每一種物品都可以無限取。
代碼如下:

#include<bits/stdc++.h> using namespace std;const int maxx=1e3+100; int dp[maxx]; int w[maxx]; int v[maxx]; int n,m;int main() {scanf("%d%d",&n,&m);//m為總價值for(int i=0;i<n;i++) scanf("%d%d",&w[i],&v[i]);memset(dp,0,sizeof(dp));for(int i=0;i<n;i++){for(int j=w[i];j<=m;j++)//這個是正序,和01背包僅此不同而已{dp[j]=max(dp[j],dp[j-w[i]]+v[i]);}} cout<<dp[m]<<endl;return 0;}

3.多重背包問題

題目
有N種物品和一個容量為V的背包。第i種物品最多有p[i]件可用,每件費用是w[i],價值是v[i]。求解將哪些物品裝入背包可使這些物品的費用總和不超過背包容量,且價值總和最大。

多重背包,每一種物品不是無限制取,而是有一個限制。

代碼如下:
這個代碼是一個例題的代碼,[藍橋杯][算法提高VIP]貪吃的大嘴

#include<bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f using namespace std;const int maxx=2e4+100; struct node{int num;int val; }p[maxx]; int dp[maxx]; int V,m;int main() {scanf("%d%d",&V,&m);for(int i=1;i<=m;i++) scanf("%d%d",&p[i].val,&p[i].num);memset(dp,inf,sizeof(dp));dp[0]=0;for(int i=1;i<=m;i++)//多重背包模板{int num=min(p[i].num,V/p[i].val);for(int k=1;num>0;k<<=1){if(k>num) k=num;num-=k;for(int j=V;j>=p[i].val*k;j--){dp[j]=min(dp[j],dp[j-p[i].val*k]+k);}}}if(dp[V]==inf) cout<<"><"<<endl;else cout<<dp[V]<<endl;return 0; }

4.分組背包問題

問題
有N件物品和一個容量為V的背包。第i件物品的費用是w[i],價值是v[i]。這些物品被劃分為若干組,每組中的物品互相沖突,最多選一件。求解將哪些物品裝入背包可使這些物品的費用總和不超過背包容量,且價值總和最大。

代碼如下:

#include<bits/stdc++.h> using namespace std;const int maxx=2e3+100; int dp[maxx]; int v, n, t; int we[maxx], c[maxx]; vector<int>ve[maxx];int main() {int p;cin >> v >> n >> t;for(int i = 1; i <= n; i++){scanf("%d%d%d", &we[i], &c[i], &p);ve[p].push_back(i);}for(int i = 1; i <= t; i++)//注意三重循環的順序,第一層遍歷的是組數,第二層遍歷的是價值(倒序),第三層遍歷的是每一組的物品。{for(int j = v; j >= 0; j--){for(int k = 0; k < ve[i].size(); k++){int x = ve[i][k];if (j >= we[x]) dp[j] = max(dp[j], dp[j-we[x]]+c[x]);}}}printf("%d\n", dp[v]);return 0; }

有什么不對的地方請大佬指針,謝謝~。
努力加油a啊,(o)/~

總結

以上是生活随笔為你收集整理的01背包,完全背包,多重背包,分组背包的使用条件以及代码模板的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。