您的位置:首页 > 其它

动态规划之背包问题,最基础的动态规划

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;}
这个是程序的运行结果,我是按表出值的,和表反了一下,应该可以看懂的。

上面的程序已经进行了详细的说明,如果还是不理解,那么我建议自己按照值在纸上面一步一步运行一下主程序。我试过,对于找错很有用。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: