关于01背包问题优化的时候为什么不能正向跑
2016-04-11 21:16
387 查看
假设有两个物品 第一个物品 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;
}
在将背包由二维转化为一维进行优化的时候
如果正常逆序进行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;
}
相关文章推荐
- 生成短链(网址) ShortUrlLink
- 文章标题
- mysqlwhere子句进行条件选择
- 设计模式之策略(Strategy)模式
- linux文档详解
- fastjson生成和解析json数据
- 计算机组成原理课程设计 - 基本模型机
- [C#]UDP实现广播
- 从Node.js的child_process模块来学习父子进程之间的通信
- 数据挖掘/机器学习 之 距离测度
- java基础随笔-overload和override
- sigmoid
- jvm虚拟机整理
- [Lintcode]Singleton
- android 使用OkHttp上传多张图片
- 迷宫问题
- POJ 【2739】 Sum of Consecutive Prime Numbers
- ACM-1001
- Hadoop安全模式详解及配置
- CSS3实战之box-shadow篇