动态规划 0-1背包问题

Posted tuilinengshou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划 0-1背包问题相关的知识,希望对你有一定的参考价值。

1、多阶段决策问题

(1)物品无限的背包 问题

比较原来的硬币问题发现,只是增加了一个重量属性,从而由原来的无权图变成了带权图,这样问题就变成了求以C为起点(终点任意)的、边权之和最大的路径,相对的

d(s)=max(d(s-v[i])+1)变为d(s)=max(d(s-v[i])+w[i])。

(2)0-1背包问题

状态及其转移类似于回溯法中的解答树,解答树的层数,也就是递归函数中的当前填充位置cur,描述的是即将完成的决策序号,在动态规划中称为阶段。

设d(i,j)表示当前在第i层,背包剩余容量为j时接下来的最大重量和,d(i,j)=maxd(i+1,j),d(i+1,j-v[i])+w[i],边界是i>n时,d=0。简单来说d(i,j)表示把第i,i+1,,,n个物品撞到容量为

j的背包中的最大总重量。

for(int i=n;i>=1;i--)
    for(int j=0;j<=C;j++)
    
        d[i][j]=(i==n?0:d[i+1][j]);
        if(j>=v[i]) d[i][j]>?=d[i+1][j-v[i]]+w[i];

2、规划方向

还可以对称定义:f(i,j)表示把前i个物品装到容量为j的背包中的最大总重量。

f(i,j)=maxf(i-1,j),f(i-1,j-v[i])+w[i],最终答案f(n,C)

for(int i=1;i<=n;i++)
    for(int j=0;j<=C;j++)
    
        f[i][j]=(i==0?0:f[i-1][j]);
        if(j>=v[i]) f[i][j] >?=f[i-1][j-v[i]]+w[i];

3、滚动数组

memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)

    scanf("%d%d",&v,&w);
    for(int j=C;j>=0;j--) 
        if(j>=v) f[j] >?=f[j-v]+w;

在递推法中,如计算顺序很特殊,且计算新状态用到的原状态不多,可以尝试滚动数组。但是会让解的打印方案变得复杂。如要求字典序最小的打印方案,则慎用滚动数组,且规划方向也一般用后i个物品最大重量的规划方向。

以上是关于动态规划 0-1背包问题的主要内容,如果未能解决你的问题,请参考以下文章

动态规划-多重背包问题

动态规划,0/1背包,完全背包

10.动态规划——0-1背包问题

0-1背包问题_动态规划

小白学习动态规划:0-1背包

动态规划-背包问题