背包问题

01背包问题:每件物品只有一件,可以选择放或不放(即取0件或1件,故名01)

代码很短:

1、最多能创造多少价值?

初始化:

for(int v=0;v<=V;++v) d[v]=0;

代码:

for(int i = 0; i < N; i++)
for(int v = c[i] ; v < V; v++)
 d[i][v] = max{d[i-1][v], d[i-1][v-c[i]]+w[i]};

优化空间后的如下:

for(int i = 0; i < N; i++)
for(int v = V ; v >=c[i]; v--)
 d[v] = max{d[v], d[v-c[i]]+w[i]};

2、背包放满时,最多(最少)能创造多少价值?

这个问题的前提是背包必须要放满,所以我们的初始条件要改变,原来我们可以一件东西都不放,这是最大的价值是0,但在这个问题下是不允许的

所以只有在容量为0时最大价值为零,即d[0] = 0,将其他设为-∞,这样循环下来只有当包的容量恰好填满的时候d[v]才有值。

初始化:

d[0]=0;
for(int v=1;v<=V;++v) d[v]=-∞;

其他不变:

for(int i = 0; i < N; i++)
for(int v = V ; v >=c[i]; v--)
 d[v] = max{d[v], d[v-c[i]]+w[i]};

3、背包放满时,总共有多少种方案?

 

完全背包问题:完全背包中,每件物品可以放无穷件。

一些优化:

1.若两件物品i、j满 足Ci ≤ Cj且Wi ≥ Wj,则将可以将物品j直接去掉,不用考虑。 的O(N2)

2.首先将费用大于V 的物品去掉,然后使 用类似计数排序的做法,计算出费用相同的物品中价值最高的是哪个,可 以O(V + N)地完成这个优化O(V + N)

主要代码:

内层循环恢复正序,这样更新d[v]的时候就可以算上多次加入自己的情况

for(int i=1;i<=N;++i)
    for(int v=Ci;v<=V;++v) d[v]=max(d[v],d[v-Ci]+Wi);

多重背包问题

 

转载于:https://www.cnblogs.com/Lune-Qiu/p/8963646.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值