背包问题

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);

多重背包问题

 

posted @ 2018-05-12 16:22  Lune-Qiu  阅读(172)  评论(0编辑  收藏  举报