演算法 揹包九講

2022-05-05 20:48:08 字數 4219 閱讀 9852

例題參考《資訊學奧賽一本通》

初始化分兩種情況

1、如果揹包要求正好裝滿則初始化 f[0] = 0, f[1~v] = -inf;

2、如果不需要正好裝滿 f[0~v] = 0;

有n件物品和乙個容量為v的揹包。第i件物品的費用(即體積,下同)是w[i],價值是c[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。

例題【問題描述】

乙個旅行者有乙個最多能用m公斤的揹包,現在有n件物品,它們的重量分別是w1,w2,...,wn,它們的價值分別為c1,c2,...,cn.若每種物品只有一件求旅行者能獲得最大總價值。

【輸入格式】

第一行:兩個整數,m(揹包容量,m<=200)和n(物品數量,n<=30);

第2..n+1行:每行二個整數wi,ci,表示每個物品的重量和價值。

【輸出格式】

僅一行,乙個數,表示最大總價值。

【樣例輸入】package.in

10 4

2 1

3 3

4 5

7 9

【樣例輸出】package.out

12解法一

#includeusing namespace std;

const int maxn=201,maxn=31;

int m,n;

int w[maxn],c[maxn];

int f[maxn][maxm];

int max(int x,int y) //求x和y最大值

int main()

解法二

#includeusing namespace std;

const int maxm=2001,maxn=31;

int m,n;

int w[maxn],c[maxn];

int f[maxm];

int main()

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

#includeusing namespace std;

const int maxm=201,maxn=31;

int m, n;

int w[maxn],c[maxn];

int f[maxn][maxm];

int main()

解法二

#includeusing namespace std;

const int maxm=2001,maxn=31;

int n,m,v,i;

int c[maxn],w[maxn];

int f[maxm];

int main()

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

#includeusing namespace std;

int n,m;

int f[6002];

int v[6002],w[6002],s[6002];

int main()

cout《解法二(二進位制優化)

#includeusing namespace std;

int n,m;

int f[6002];

int v[6002],w[6002];

int v1,w1,s;

int n1=0;

int main()

if(s>0)//多出來的一起打包

}for(int i=1;i<=n1;i++)

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

cout《將01揹包、完全揹包、多重揹包混合起來。也就是說,有的物品只可以取一次(01揹包),有的物品可以取無限次(完全揹包),有的物品可以取的次數有乙個上限(多重揹包)。

#includeusing namespace std;

int m,n;

int w[31],c[31],p[31];

int f[201];

int max(int x,int y)

int main()

else

printf("%d",f[m]);

return 0;

}

二維費用的揹包問題是指:對於每件物品,具有兩種不同的費用;選擇這件物品必須同時付出這兩種代價;對於每種代價都有乙個可付出的最大值(揹包容量)。問怎樣選擇物品可以得到最大的價值。設這兩種代價分別為代價1和代價2,第i件物品所需的兩種代價分別為a[i]和b[i]。兩種代價可付出的最大值(兩種揹包容量)分別為v和u。物品的價值為c[i]。

#include#include//初始化memset要用到

using namespace std;

int v,u,k;

int a[1001],b[1001],c[1001];

int f[101][101];

int main()

printf("%d",f[v][u]);

return 0;

}

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

#includeusing namespace std;

int v,n,t;

int w[31],c[31];

int a[11][32],f[201];

int main()

for(int k=1;k<=t;k++)

for(int j=v;j>=0;j--)

for(int i=1;i<=a[k][0];i++)

if (j >= w[a[k][i]])

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

for(int j=1;j<=m;j++)//尋找i的附件

}for(int k=v[i];k<=n;k++)

if(t[k]>s[k])

s[k]=t[k];//替換有比原有答案大的新答案 }}

}cout《對於乙個給定了揹包容量、物品費用、物品間相互關係(分組、依賴等)的揹包問題,除了再給定每個物品的價值後求可得到的最大價值外,還可以得到裝滿揹包或將揹包裝至某一指定容量的方案總數。

對於這類改變問法的問題,一般只需將狀態轉移方程中的max改成sum即可。例如若每件物品均是01揹包中的物品,轉移方程即為f[i][v]=sum,初始條件f[0][0]=1。

事實上,這樣做可行的原因在於狀態轉移方程已經考察了所有可能的揹包組成方案。

【問題描述】

給你乙個n種面值的貨幣系統,求組成面值為m的貨幣有多少種方案。樣例:設n=3,m=10,要求輸入和輸出的格式如下:

【樣例輸入】money.in

3 10 //3種面值組成面值為10的方案

1 //面值1

2 //面值2

5 //面值5

【樣例輸出】money.out

10 //有10種方案

#includeint m,n;

int a[1001];

long long f[10001]; //注意要用long long

int main()

總的來說揹包問題並不難理解

主要是題目的靈活性需要考慮到底要使用什麼揹包

還有 每個揹包的**基本相似

但卻有個別的差別

所以要搞清楚每個變數的定義

最好是要把**背下來考試時才不會want to go die

揹包九講 簡單揹包

揹包問題是一種動態規劃演算法的衍生問題。它可以被看作一種獨立的題型,也可以看作是一種線性動態規劃。學好揹包 學會揹包,對於深入理解動態規劃演算法有著極大的好處,並能幫助理解一些更深層次的動態規劃問題。那麼就開始吧 題目型別 有 n 件物品和乙個容量為 v 的揹包。第 i 件物品的費體積是 v i 價...

揹包九講(9)

以上涉及的各種揹包問題都是要求在揹包容量 費用 的限制下求可以取到的最大價值,但揹包問題還有很多種靈活的問法,在這裡值得提一下。但是我認為,只要深入理解了求揹包問題最大價值的方法,即使問法變化了,也是不難想出演算法的。例如,求解最多可以放多少件物品或者最多可以裝滿多少揹包的空間。這都可以根據具體問題...

揹包九講(5)

問題二維費用的揹包問題是指 對於每件物品,具有兩種不同的費用 選擇這件物品必須同時付出這兩種代價 對於每種代價都有乙個可付出的最大值 揹包容量 問怎樣選擇物品可以得到最大的價值。設這兩種代價分別為代價1和代價2,第i件物品所需的兩種代價分別為a i 和b i 兩種代價可付出的最大值 兩種揹包容量 分...