用一維和二維陣列解決超大揹包問題

2022-07-23 05:36:13 字數 2352 閱讀 6594

現在有乙個容量為c的揹包和n個重量和價值已知的物品. 現在要從這n個物品中挑選出一些物品, 使得選擇的物品的總重量不超過揹包的容量,

且總價值最大.

此題的資料範圍:

1 <= c <= 10^8(10的8次方)

1 <= n <= 100

輸入描述

有多組測試資料. 第一行乙個正整數t(t<=15), 表示測試資料組數.

對於每組測試資料:

第一行兩個正整數n和c, 分別表示物品的數量和揹包的容量.

接下來n行, 每行兩個正整數w,v ,分別表示對應物品的重量和價值(1<= w <= 10^7, 1<= v <= 100)

輸出描述

輸出乙個正整數, 表示在所選物品不超過揹包容量的情況下, 能夠得到的最大價值.

輸入樣例

13 10

5 10

5 10

4 12   

輸出樣例

22建議閱讀完我上篇博文再來看這篇,有了0-1揹包的基礎後,我們可以分析

因為c的資料範圍過大,所以不能再把它當成二維陣列的縱座標了,仔細想一想,其實可以把價值當做縱座標來填表。

因為價值的資料範圍還比較合理,那麼**中的資料就是前i個物品挑選價值總和為j時揹包的最小容量了(不存在就賦值inf)。

然後填完二維陣列後,我們直接找到最後一行,從最高的價值即物品價值總和一直往前推(也就是遞減)揹包最小容量時,

會有乙個臨界點,就是最小容量,剛好<=c,此時又正好滿足揹包價值最大,因此這個點的縱座標就是題目的答案了。

#includeusing

namespace

std;

#define n 5500 //注意這裡的範圍要根據物品價值總和來確定

#define min(a,b) a>b?b:a

#define ll long long

#define inf 0x3f3f3f3f;

int c[n][n];//

c[i][j]表示在前i個物品中挑出價值總和為j時揹包容量的最小值(不存在就賦值inf)。

int fill(int n,int c,int w,int

v) c[

0][0]=0;//

這裡一定要初始化為0 前0個物品價值為0時揹包最小容量也為0

for(i=1;i<=n;i++)

}for(j=vsum;j>=0;j--)//

二維陣列最後一行逆序尋找那個臨界點:前n個物體下,價值為j的揹包的最小容量

}int

main()

return0;

}

上述是二維陣列的做法

下面來介紹一維陣列的做法

和0-1揹包類似,內層for迴圈要逆序,因為每一次外層迴圈都會更新一維陣列,而後面的值又是由前面的值構成的,所以要逆序更新

#include#include

using

namespace

std;

//#define ll long long 可以直接用int,int和long是一樣的,也沒必要用long long

#define n 5500 //

如果這裡n範圍設得小而測試資料很大的話,會出現除0越界錯的警告,

const

int inf=0x3f3f3f3f;//

10的九次方級別

double c[n],w[n],c; //

因為n是其他陣列的最大下標,所以要兼顧全域性 這裡int也可以,不過設為double更加保險,範圍會大一些

intv[n];

intn,vsum;

intmain()

//這裡一定要初始化為較大的數,否則結果就不對

for(int j=0;j<=vsum;j++)

c[j]=inf;

c[0]=0;//

0價值物品容量為0

//c[j]開始表示揹包價值為j時所需要的最小容量 從j=vsum開始

for(int i=1;i<=n;i++)

//for(int j=vsum;j>=v[i];j--)

//c[j]=min(c[j],c[j-v[i]]+w[i]); 這兩個for迴圈是等價的 隨便哪個都可以

}

//從大到小遍歷價值,第乙個滿足條件的陣列值的下標便是答案

for(int j=vsum;j>=0;j--)}}

return0;

}

用二維和一維陣列解決0 1揹包問題

0 1揹包問題 物品集合u u1,u2 un 體積分別為s1,s2 sn,價值分別為v1,v2 vn 容量c的揹包。設計演算法實現放入揹包的物品價值最大。輸入描述 第一行輸入物品數n和揹包的容量c,接下來n行分別輸入每個物品體積及價值 輸出描述 輸出最大價值數 輸入樣例 3 10 3 4 4 5 5...

一維和二維字首和

出自南昌理工學院acm集訓隊 二維字首和 字首和是什麼呢?字首就是乙個陣列的某項下標之前 包括此項元素 的所有陣列元素的和。簡單點來說就是有n個數,求n個數包括第n個數的所有數的和。s n a 1 a 2 a 3 a 4 a n 字首和最基本的用法就是解決求某個區間所有數的和,經過字首和的預處理,可...

01揹包 分組揹包(一維 二維 搜尋

上面的 中寫了01揹包 分組揹包的一維,二維陣列方法,還有搜尋法以及自己的一些思考。個人對於網上分組揹包的二維轉移方程覺得還不太完善 或者我自己理解的不太對 而且沒有找到很完全的 可能恰好沒找到 所以就自己寫了,有附題目位址,如果想看二維陣列分組揹包,直接拉到最後,前面都是廢話。不想看原位址的,下面...