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



这次做动态规划是用的二维数组来写,一维数组还没有想,如果以后做了会再补充。下面我们来开始了解:

动态规划的特性和基础知识可以参考相关书籍,这次主要讲解背包问题的详细理解。

题目:有n件物品和一个容量为v的背包。第i件物品的重量是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

我们可以来参考这个表来进行思路理解。


这个表是按从上到下的顺序开始的,咱们应该知道填写的原则,那就是使背包中物品价值总和最大

大家可以先自己长试着写这个表,看自己写的是否正确。

然后我们从这个表中来找一下规律。例如:有4件物品,背包容量为10,那么根据表里面填的我们知道最大价值和为14。那这个数肯定不是一下子得来的,它需要前面的累积。重点是这个积累的过程,它涉及到排除和比较。下面是代码,我会重点进行逐步解释。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 1001
int ans[N][N];//二维数组,记录的是表中每个的最大价值总和
int n,v,c[N],w[N];
int max(int a,int b)
{
	if(a>=b)
		return a;
	else
        return 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];//因为容量不够,所以不能装下,直接得到上一步的值。
				else
                    ans[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;
}
这个是程序的运行结果,我是按表出值的,和表反了一下,应该可以看懂的。


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






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值