欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

完全背包

程序员文章站 2022-03-24 20:32:51
...

                                                     完全背包问题

有 n 种重量和价值分别为 wi 和 vi 的物品 , 从这些物品中挑选总重量不超过 W 的物品,使得挑选出的物品的总价值最大。

和0-1 背包相比,完全背包对于每一件物品可以挑选任意多件。

转移方程: 

                                          完全背包            

                                          完全背包

void solve() {
    for(int i = 0 ; i<n ; i++ ) {
        for(int j = 0 ; j<=W; j++) {
            for(int k = 0 ; k*w[i] <=j ; k++ ) {
                dp[i+1][j] = max(dp[i+1][j] , dp[i][j-k*w[i]] + k*v[i]) ; 
            }
        }
    }
    cout<< dp[n][W] ; 
}

完全背包

     我们看它的状态转移,对于 dp[3][3] 它是由 dp[2][1] 和 dp[2][3] 转移的 , 对于 dp[3][5] , 它是由 dp[2][1] 和 dp[2][3] 以及 dp[2][5]转移的,同理 dp[3][7] 是由 dp[2][1] 和 dp[2][3] 以及 dp[2][5] ,以及 dp[2[7] 转移的.

我们发现,可以简化为dp[3][5]是由 dp[3]3] 和 dp[2][5] 转移的,对于 dp[3][7] 是由 dp[3][5] 和dp[2][7] 转移的,这时, 每个状态都是由两个状态转移的。

完全背包

上图就是简化后的,

void solve1() {

    for(int i = 0 ; i<n ; i++ ) {
            for(int j = 0 ; j<=W; j++) {
                if(j<w[i]){
                    dp[i+1][j] = dp[i][j] ; 
                }else {
                    dp[i+1][j] = max(dp[i][j] , dp[i+1][j-w[i]] + v[i]) ; 
                }
                
            }
        }
        cout<< dp[n][W] ; 

}

这时的转移方程变成 : 

                                          完全背包

空间优化 :

void solve3() {

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

}

 

相关标签: # 背包问题