01背包和完全背包比较容易忽略的地…

01背包和完全背包比较容易忽略的地方

01背包:
      1、for(i = 1; i <= n; i++)
      {
            for(j = v; j >= c[i]; j--)  //
            {
                  f[j] = max(f[j] , f[j-c[i]] + w[i]);
            }
      }
              2、for(i = 1; i <= n; i++)
      {
            for(j = c[i]; j <= v; j++)  //
            {
                  f[j] = max(f[j] , f[j-c[i]] + w[i]);
            }
      }

这个两个是01背包状态转移的两种写法 , 它们的区别是:
1是对的 ,而2是错的 。

因为在01背包中每件物品是只有一件的 , 所以状态转移方程可以是这个f[i][j] = max(f[i-1][j] , f[i-1][j-c[i]] + w[i])  , 但不能是这个f[i][j] = max(f[i-1][j] , f[i][j-c[i]] + w[i]) , 这就是它们的区别。

下面给出数据样例:
v = 10
c: 2  3
w: 2  5


完全背包:
              1、for(i = 1; i <= n; i++)
      {
            for(j = 1; j <= v; j++)
            {
                  int k = j/c[i];
                  f[j] = max(f[j] , f[j-k*c[i]] + k*w[i]);//
            }
      }
              2、for(i = 1; i <= n; i++)
      {
                              int k = j/c[i];
            for(j = v; j >= 1; j--)
            {
                  int k = j/c[i];
                  f[j] = max(f[j] , f[j-k*c[i]] + k*w[i]);//
            }
      }
完全背包的这两个状态转移代码的不能之处和01背包是一样 , 但是在这里1和2都是对了。

在完全背包中每个物品都无限多的而不是只有一件 , 所以下面这两个状态转移方程是一样的:

1、f[i][j] = max(f[i-1][j] , f[i-1][j-k*c[i]] + k*w[i])
2、f[i][j] = max(f[i-1][j] , f[i][j-k*c[i]] + k*[i])

理解:假设有一件物品x的体积是c、价值是w , 当j < c时  ,我们可以确定f[i][j] = f[i-1][j],因为这个时候袋子的体积小于c,则这个袋子连一件物品x都不能装下 。 那么 当k = j/c[i]时 ,  f[i][j-k*c[i]] = f[i-1][j-k*c[i]] , 因为j-k*c[i] < c[i] 。 所以对于完全背包来说 , 代码1和代码2是完全一样的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值