【揹包問題】0-1揹包、徹底揹包、多重揹包、混合三種揹包、二位費用揹包、分組揹包

1、0-1揹包問題php

       輸入:第一行物品的個數n,第二行揹包的質量m,隨後n行每行給出每一個物品的重量和價值,每種物品只有一個。html

       輸出:揹包能夠達到的最大價值ios

樣例輸入:數組

5 10優化

1 5spa

2 4code

3 3htm

4 2blog

5 1ip

樣例輸出:

14

 

動態規劃的過程當中須要逆序,由於若是不是逆序那麼

當i=0的時候

f[0]=0;

f[1]=max(f[1],f[1-w[0]]+v[0])=5;

f[2]=max(f[2],f[2-w[0]]+v[0])=10;

f[3]=max(f[3],f[3-w[0]]+v[0])=15;

….

f[10]=max(f[10],f[10-w[0]]+v[0])=50

顯然不對,由於每種物品只有一個,而順序遍歷可能會用到第i件物品在前一種狀態已經放入的狀況

 

 

#include <iostream>
#include <cstring>

using namespace std;
int n,m,f[1111],w[1111],v[1111];
//m揹包的總容量、v物品的體積、w物品的價值
void OneZeroPack(int m,int v,int w)  //0-1揹包
{
    for(int i=m;i>=v;i--)
        f[i]=max(f[i],f[i-v]+w);
}
int main()
{
    while(cin>>n>>m)
    {
        for(int i=0;i<n;i++)
            cin>>v[i]>>w[i];
        memset(f,0,sizeof(f));
        for(int i=0;i<n;i++)
            OneZeroPack(m,v[i],w[i]);
        cout<<f[m]<<endl;
    }
    return 0;
}

若是須要所有裝滿,那麼初始化數組的時候,只把f[0]=0其他的賦值-∞

2、徹底揹包問題

       輸入:第一行物品的個數n,第二行揹包的質量m,隨後n行每行給出每一個物品的重量和價值,每種物品有無限多個。

       輸出:揹包能夠達到的最大價值

樣例輸入:

5 10

1 5

2 4

3 3

4 2

5 1

樣例輸出:

50

若是每種無限多個那就應該是順序遍歷,上面解釋過。。。

代碼:只在上面那個基礎上改這一點就行

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

3、多重揹包

       和徹底揹包很類似,對於每件物品有num[i]+1中策略:0件,1件,2件…num[i]件,則有狀態轉移方程:f[i][v] = max{F[i−1][v−k∗Ci] + k∗Wi |0 ≤ k ≤ Mi}

複雜度是O(V ΣMi)

  二進制優化時間複雜度O(VNlogM)

能夠轉化爲0-1揹包問題直接求解,複雜度仍 然是O(V ΣMi)。可是咱們能夠經過二進制的思想進行優化下降時間複雜度。將第i種物品分紅若干件物品,此中每件物品有一個係數,這件物品的費用和價值均是原本的費用和價值乘以這個係數。使這些係數分別爲 1,2,4,...,2^(k-1),n[i]-2^k+1,且k是知足n[i]-2^k+1>0的最大整數。例如,如果n[i]爲13,就將這種 物品分紅係數分別爲1,2,4,6的四件物品。

原題連接:http://acm.hdu.edu.cn/showproblem.php?pid=2844 

解題報告:http://www.cnblogs.com/asuml/p/5730400.html

 

 

4、混合三種揹包

       很好理解直接附上僞代碼:

              for i=0 to n-1

                     if i爲0-1揹包

                            OneZeroPack(int m,int v,int w)

                     Else if i爲徹底揹包

                                   CompletePack(int m,int v,int w)

                            Else

                                   MultiplePack(int m,int v,int w,int num)

 

5、二維費用的揹包

       費用加了一維狀態對應的增長一維便可

三維轉移方程:F[i,v,u] = max{F[i−1,v,u],F[i−1,v−Ci,u−Di] + Wi}

       二維轉移方程:F[v,u]=max{F[v,u],F[v−Ci,u−Di] + Wi}

6、分組的揹包問題

       1.問題

有N件物品和一個容量爲V 的揹包。第i件物品的費用是Ci,價值是Wi。這 些物品被劃分爲K組,每組中的物品互相沖突,最多選一件。求解將哪些物品 裝入揹包可以使這些物品的費用總和不超過揹包容量,且價值總和最大。

       2.轉移方程:

              F[k,v] = max{F[k−1,v],F[k−1,v−Ci] + Wi |item i ∈ group k}

       3.僞代碼:

              For k=1 to K

                     For v=V to 0

                            For 全部的i屬於組k

                                   F[v]=max{f[v],f[v-c[i]]+a[i]

       原題連接:http://acm.hdu.edu.cn/showproblem.php?pid=1712

       解題報告:http://www.cnblogs.com/asuml/p/5732073.html

相關文章
相關標籤/搜索