关于01背包问题优化的时候为什么不能正向跑

假设有两个物品 第一个物品 w=2 v=1 第二个物品 w=2 v=2
在将背包由二维转化为一维进行优化的时候
如果正常逆序进行dp
dp[1][4]=1; dp[1][2]=1; dp[2][4]=max(dp[1][4],dp[1][4-2]+2)=3; dp[2][2]=2;
这是正确做法
但是如果正序进行dp
do[1][4]=1; dp[1][2]=1; dp[2][2]=2; dp[2][4]=max(dp[1][4],dp[2][4-2]+2)=4;
注意上面为dp[1][4-2]而下面为dp[2][4-2] 原因是dp[2][2]已更新
出错的原因就是 第二个物品取了两次 其实这也就是完全背包的来源
就是dp[i][j]由dp[i][j-w[i]]+v[i]推过来的 而不是dp[i-1][j-w[i]]+v[i]
会导致结果偏大

最初的想法为顺序会更对 结果更大更准确
经代码验证想法错误 但是发现了完全背包
下一步多重背包
以下为验证代码:

#include <iostream>
#include <string.h>
using namespace std;
int dp[1005];
int main()
{
int i,j,n,m,t;
int v[1005]={0};
int w[1005]={0};
cin>>t;
while(t--)
{
cin>>n>>m;
memset(dp,0,sizeof(dp));
memset(v,0,sizeof(v));
memset(w,0,sizeof(w));
for(i=1;i<=n;i++)
cin>>v[i];
for(i=1;i<=n;i++)
cin>>w[i];

//正确的逆向跑
for(i=1;i<=n;i++)
{for(j=m;j>=w[i];j--)
{
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
cout<<dp[j]<<" ";
}cout<<endl;
}
cout<<endl<<endl;

//错误的正向跑
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{for(j=w[i];j<=m;j++)
{
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
cout<<dp[j]<<" ";
}cout<<endl;
}
cout<<endl;
//cout<<dp[m]<<endl;
}
return 0;
}

时间: 2024-12-10 21:38:31

关于01背包问题优化的时候为什么不能正向跑的相关文章

6、0-1背包问题优化

0-1背包问题优化 关于0-1背包问题的优化,其实一开始也觉得分配的内存确实太多了,对于物品数为N,背包容量为W的背包问题 则我们每次需要分配的内存是N*W,这确实不太好. 于是我们是否可以使用一个一维数组来代替前面算法的二维数组问题呢? 这好像是可以的,因为我们的想法是自底向上,其实对于W*N的二维数组,对于数组select[i][w]所代表的意思是 在背包容量为w,可以选的物品为前i个时它所能达到的最大价值,我们可以看到所记录的前面i个背包所能达到最 大的价值是浪费,我们所关心的只是在N个物

动态规划 - 0-1背包问题的算法优化

简单描述 0-1背包问题描述如下: 有一个容量为V的背包,和一些物品.这些物品分别有两个属性,体积w和价值v,每种物品只有一个.要求用这个背包装下价值尽可能多的物品,求该最大价值,背包可以不被装满.因为最优解中,每个物品都有两种可能的情况,即在背包中或者不存在(背 包中有0个该物品或者 1个),所以我们把这个问题称为0-1背包问题. 0-1背包问题状态转移方程 用dp[i][j]表示前i个物品在总体积不超过j的情况下,放到背包里的最大价值.由此可以推出状态转移方程: dp[0][j] = 0;

01背包问题(空间优化)经典代码

题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. 基本思路 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.则其状态转移方程便是: f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} 这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的.所以有必要将它详细解释一下

关于01背包问题的优化

一.01背包问题介绍 背包问题是经典的动态规划问题之一: 常见的01背包问题就是说有一堆物品,现在要装入一个容器中,这些物品的重量和价值各不一致,而容器的重量又是有限的,没种物品只能装1个或者不装(0个),求当重量限定为w时,这些物品能装进去组合成的最高价值是多少? 分析:我们首先将物品排成一排(随机),依次标记为1号,2号....然后从一号开始依次往里放,放的时候判断当前物品是不是应该放进去: 如果当前物品放进去之后的最高总价值 比 不放进去的最高总价值 大 ,那么就是要放入,然后总价值取放入

优化算法系列-模拟退火算法(1)——0-1背包问题

优化算法系列之模拟退火算法(1)--0-1背包问题 1问题描述 有一个窃贼在偷窃一家商店时发现有N件商品:第i件物品价值vi元,重wi磅,其中vi.wi都是整数.他希望带走的东西越值钱越好,但他的背包小,最多只能装下W磅的东西(W为整数).如果每件物品或被带走或被留下,小偷应该带走哪几件东西? 2解空间 设xi表示第i件物品的取舍,1代表取,0代表舍,搜索空间为n元一维数组(x1,x2,x3,.....,xn).因而解空间的取值范围可表示为(0,0,0,....,0),(0,0,0,......

01背包问题:POJ3624

背包问题是动态规划中的经典问题,而01背包问题是最基本的背包问题,也是最需要深刻理解的,否则何谈复杂的背包问题. POJ3624是一道纯粹的01背包问题,在此,加入新的要求:输出放入物品的方案. 我们的数组基于这样一种假设: totalN表示物品的种类,totalW表示背包的容量 w[i]表示第i件物品的重量,d[i]表示第i件物品的价值. F(i,j)表示前i件物品放入容量为j的背包中,背包内物品的最大价值. F(i,j) = max{ F(i-1,j) , F(i-1,j-w[i])+d[i

01背包问题

01背包问题详解 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. 基本思路 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.则其状态转移方程便是: f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} 这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的.所以有必

01背包问题的学习(来源:背包九讲)

问题: 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. 思路: 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放.用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}.这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的.所以有必要将它详细解释一下:"

《算法导论》读书笔记之第16章 0-1背包问题—动态规划求解

原文:http://www.cnblogs.com/Anker/archive/2013/05/04/3059070.html 1.前言 前段时间忙着搞毕业论文,看书效率不高,导致博客一个多月没有更新了.前段时间真是有些堕落啊,混日子的感觉,很少不爽.今天开始继续看算法导论.今天继续学习动态规划和贪心算法.首先简单的介绍一下动态规划与贪心算法的各自特点及其区别.然后针对0-1背包问题进行讨论.最后给出一个简单的测试例子,联系动态规划实现0-1背包问题. 2.动态规划与贪心算法 关于动态规划的总结