动态规划三部曲之01背包问题的分析和实现(二)
2015-06-30 10:28
756 查看
用w[i]表示第i件物品的重量
用v[i]表示第i件物品的价值
用f[i][j]表示用能 装下总重量为j的背包去装前i件物品能够装最大的价值
思考动态规划的第一点----最优子结构:
对于前i件物品,以及给定的包容量,要么第i件物品装进去,要么不装进去,f[i][j]必然存在于二者之一。
思考动态规划的第二点----子问题重叠:
对于任意前k件物品,最大价值f[k]
都是同一类问题,即子问题重叠
思考动态规划的第三点----边界:
显然当包承重j为0时,f[i][j]=0,当物品件数为0时,f[i]j]=0这就是边界条件
思考动态规划的第四点----子问题独立:
第i件物品选择或者不选择是没有任何相互之间的影响的,即二者之间相互独立。
源码实现如下:
用v[i]表示第i件物品的价值
用f[i][j]表示用能 装下总重量为j的背包去装前i件物品能够装最大的价值
思考动态规划的第一点----最优子结构:
对于前i件物品,以及给定的包容量,要么第i件物品装进去,要么不装进去,f[i][j]必然存在于二者之一。
思考动态规划的第二点----子问题重叠:
对于任意前k件物品,最大价值f[k]
都是同一类问题,即子问题重叠
思考动态规划的第三点----边界:
显然当包承重j为0时,f[i][j]=0,当物品件数为0时,f[i]j]=0这就是边界条件
思考动态规划的第四点----子问题独立:
第i件物品选择或者不选择是没有任何相互之间的影响的,即二者之间相互独立。
源码实现如下:
#include<iostream> using namespace std; int package01(int w[],int v[],int m,int n,int **&fm,int *&result) { int maxValue=0; int x,y;//记录去取得最大值时f的坐标 int**f=(int **)malloc((m+1)*sizeof(int*)); int *results=(int *)malloc((m+1)*sizeof(int)); for(int i=0;i<(m+1);i++) { f[i]=(int *)malloc((n+1)*sizeof(int)); } for(int i=0;i<=m;i++) { f[i][0]=0; results[i]=0; } for(int j=0;j<=n;j++) { f[0][j]=0; } for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { if(j<w[i]) f[i][j]=f[i-1][j]; else { if((f[i-1][j-w[i]]+v[i])>f[i-1][j]) { f[i][j]=f[i-1][j-w[i]]+v[i]; } else f[i][j]=f[i-1][j]; } } } fm=f; result=results; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { cout<<f[i][j]<<" "; } cout<<endl; } while(y>=1&&f[x-1][y]!=f[x][y])//f[x-1][y]!=f[x][y]表示第x件物品放入了背包中 {//该函数用于逆推出最大容量选择的物品 result[x]=1; y=y-w[x]; x=x-1; } return f[i][j]; } void main() { cout<<"进来了"<<endl; int m;//物品数量 int n;//背包容量 int maxValue;//存放背包能装的最大价值 cout<<"请输入物品数量"<<endl; cin>>m; cout<<"请输入背包容量"<<endl; cin>>n; int *w=(int*)malloc(sizeof(int)*(m+1));//存放物品重量 int *p=(int*)malloc(sizeof(int)*(m+1));//存放物品价值 int *result;//存放最终选择的物品标记,如果物品被选中,则该位置置1 int **f;//存放价值的二维数组 cout<<"请输入物品重量:"<<endl; for(int i=1;i<=m;i++) { cin>>w[i]; } cout<<"你输入的物品重量为:"<<endl; for(int i=1;i<=m;i++) { cout<<w[i]<<" "; } cout<<endl; cout<<"请输入物品价格:"<<endl; for(int i=1;i<=m;i++) { cin>>p[i]; } cout<<"你输入的物品价格:"<<endl; for(int i=1;i<=m;i++) { cout<<p[i]<<" "; } cout<<endl; maxValue=package01(w,p,m,n,f,result); cout<<"外面的输出结果"<<endl; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { if(maxValue<f[i][j]) maxValue=f[i][j]; cout<<f[i][j]<<" "; } cout<<endl; } cout<<"最大价值为:"<<maxValue<<endl; cout<<"标记结果"<<endl; for(int i=1;i<=m;i++) cout<<result[i]<<" "; cout<<endl; system("pause"); }
相关文章推荐
- 黑马程序员——Java基础之多态、内部类
- [MFC] 关于OnPaint()
- 大型商贸系统(进货管理)技术解析(五)自营无订单进仓冲红单
- bzoj3632
- WebService(2)-XML系列之Java和Xml之间相互转换
- word转成pdf有什么方法
- brk()和sbrk()函数的使用
- 删除重复项的几种方法
- mysql安装最后一步 Apply Security Settings 出错
- 07、在 Windows10 上获得屏幕分辨率
- 实现输入图片地址浏览图片功能
- IOS的iPhone5s模拟器只显示3.5寸解决方法
- Spring MVC-HandlerAdapter
- Java程序设计——第十六周周五:数据库的连接与随机数使用
- what is archeage honor weapons?
- 在js中使用createElement创建HTML对象和元素
- C++ MFC 中使用多线程操作实例
- CMD命令名详细大全
- bzoj3955
- 每天收获一点点------Hadoop RPC机制的使用