动态规划装箱问题

思路:
动态规划:
假设可选物品集合为S, Sk为前k个物品组成的物品子集, 第k个物品的体积是wk,价值是vk
1. 表征子问题:用B[k,w] 表示在子集Sk中,所剩空间为w时,能够装下的物品最大价值。
2. 状态迁移方程:则从含有n个物品的集合中,用W大小的背包,能装下物品的最大价值是B[n, W],由子问题表示可知:
B[k, w] = B[k-1, w] wk > w
= max(B[k-1, w], B[k, w - wk] + vk) wk <= w

当当前物体的体积wk大于当前背包的剩余空间的时候,不选择放入物品。当当前还有空间可以放下,则是否选择放入物品,取决于放入之后可获得的价值是否大于不放入可获得的最大价值。

int B[35][20005];

int knapsack(int *W, int n, int V)
{ 
    for(int k = 1; k <= n; k++){
        for(int w = 0; w <= V; w++){
            if(w < W[k]){
                B[k][w] = B[k-1][w];
            }else{
                B[k][w] = max(B[k - 1][w], B[k - 1][w - W[k]] + W[k]);    
            }

        }
    }
    return B[n][V];
}


算法分析:
给定整数W和n个物品的集合S,每个物品有正整数型的权值,可以用O(nW)时间求出S中的总权值之多为W且具有最大效用的子集。
伪多项式时间算法:
算法的运行时间依赖于W(背包的大小),如果W很大(2^n)那么这个动态规划算法渐进的比蛮力方法要慢。
一般称像背包动态规划这样的算法为伪多项式时间算法,因为它的运行时间依赖于输入中给定的某个数的量。

改进:

依据上面的分析,可以用一个一维数组来做:
子问题:用B[w]表示在背包剩余空间为w的情况下,从Sk子集中能够选出的最大价值。
状态迁移方程:B[w] = max(B[w], B[w-wk] + vk)


int B[BUF_SIZE];

int knapsack(int *W, int n, int V)
{
    for (int k = 1; k <= n; k++) {
        for (int w = V; w >= W[k]; w--) {
            B[w] = max(B[w], B[w - W[k]] + W[k]);
        }
    }
    return B[V];
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值