动态规划之背包问题,最基础的动态规划
2015-07-29 11:35
218 查看
这次做动态规划是用的二维数组来写,一维数组还没有想,如果以后做了会再补充。下面我们来开始了解:
动态规划的特性和基础知识可以参考相关书籍,这次主要讲解背包问题的详细理解。
题目:有n件物品和一个容量为v的背包。第i件物品的重量是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
我们可以来参考这个表来进行思路理解。
这个表是按从上到下的顺序开始的,咱们应该知道填写的原则,那就是使背包中物品价值总和最大。
大家可以先自己长试着写这个表,看自己写的是否正确。
然后我们从这个表中来找一下规律。例如:有4件物品,背包容量为10,那么根据表里面填的我们知道最大价值和为14。那这个数肯定不是一下子得来的,它需要前面的累积。重点是这个积累的过程,它涉及到排除和比较。下面是代码,我会重点进行逐步解释。#include<stdio.h>#include<stdlib.h>#include<string.h>#define N 1001int ans;//二维数组,记录的是表中每个的最大价值总和int n,v,c,w;int max(int a,int b){if(a>=b)return a;elsereturn b;}int main(){int max(int,int);while(scanf("%d%d",&n,&v))//读取数量和容量{if(n==0&&v==0)return 0;//这个是说n和v同时为0是结束程序int i,j;memset(ans,0,sizeof(ans));//数组初始化,每个都赋值为0.for(i=1;i<=n;i++){scanf("%d%d",&c[i],&w[i]);//读取n个物体的重量和价值}//以下是背包问题的核心部分for(i=1;i<=n;i++)//因为得到我们需要的解是需要前面上一步的结果,所以,此时定义i从1开始,而不是从零开始{//i控制的是物品个数,j则是背包的容量大小for(j=v;j>0;j--)//j一定要大于零,背包容量不能为零{if(j<c[i])//这里需要加以判断,否则会出现得到的是初值0,而不是上一步的值ans[i][j]=ans[i-1][j];//因为容量不够,所以不能装下,直接得到上一步的值。elseans[i][j]=max(ans[i-1][j],ans[i-1][j-c[i]]+w[i]);//这里就是判断最大值//而ans[i-1][j-c[i]]+w[i]举个例子进行讲解。//例如图中,当得出ans[4][10]的最大价值和那么那个式子可化成://ans[3][10-c[4]]+w[4]=ans[3][5]+4=9+4=13,没有ans[3][10]=14大,所以得出答案14。printf("%5d",ans[i][j]);}printf("\n");}}return 0;}
这个是程序的运行结果,我是按表出值的,和表反了一下,应该可以看懂的。
上面的程序已经进行了详细的说明,如果还是不理解,那么我建议自己按照值在纸上面一步一步运行一下主程序。我试过,对于找错很有用。
相关文章推荐
- vi/vim 光标移动命令
- 收起actionbar 上的搜索框 正确写法
- sizeof和strlen的区别
- Java集合之泛型的使用
- eclipse 选中代码,提示其他相同代码
- hadoop常用操作命令
- 学习在一台新电脑上配置JAVA开发环境
- HDU 1232
- robotium 找不到控件index解决办法
- A20平台调试GPS模块
- 优先队列 - 堆
- Linux SSH 登录其他机器
- Java集合框架之map
- 原码,补码表示
- Hibernate中Criteria的完整用法
- cocoapods version update!
- Num 18: HDOJ: 题目1232 : 畅通工程 [ 并查集 ]
- Robotium 测试多个activity
- 关于安装toad for oracle 10.6的一些问题
- POJ 3126 Prime Path