动态规划:0-1背包问题(一)

第一次接触动态规划,写一些自己的心得吧,动态规划真的还是挺难理解的,看了不少大牛的相关博客后才初步有所了解,哎,无奈自己智商捉急啊。下面是动态规划最简单的一种类型0-1背包问题。

问题:

有N件物品和一个容量为V的背包。第i件物品的体积是volume[i],价值是value[i]。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。

思路:

对于每种物品来说,只有两种状态,装或者不装。于是我们就可以把它分解为子问题best[i][j],代表前i个物品放入体积为j的背包中所能达到的最大价值.这样我们就可以列出一个状态转移方程(注意:动态规划中列出状态转移方程是关键所在!呃。。。。至少大家都是这么说的。。。)那么该方程是什么呢?就像我之前所说的,对于第i件物品来说只有两种状态,装入背包或者不装。

列出如下状态转移方程:

best[i][j]=max{best[i-1][j],best[i-1][j-volume[i]]+value[i]}核心就是这个方程,如果第i件物品不装,最大价值就是best[i-1][j],如果装了,就得是不装第i件物品时的最大价值(此时的体积应该减去第i件物品的体积)加上第i件物品的价值。

定义边界值

显而易见,若不边界,则该方程会无限递归下去。由于当物品为0或者空间为0时,最大价值一定是0,所以我们可以定义best[0][j]=0,best[i][0]=0,当然我们也可以直接先让该二维数组赋初值为0,之后再改动其中部分的值。

接下来就是码代码啦:

#include <iostream>  
using namespace std;  
int max(int a,int b)  
{  
 int temp=b;  
 if (a>b)temp=a;  
 return temp;  
}   
int main()  
{  
 int N,V;  
 int best[101][100]={0};  
 int i,j;  
 int value[100]={0},volume[100]={0};  
  cin>>N>>Vfor(i=1;i<=N;i++)cin>>value[i]>>volume[i];
  for(i=0;i<=N;i++)  
   for(j=0;j<=V;j++)  
    best[i][j]=0;  
   for(i=1;i<=N;i++)  
    for(j=1;j<=V;j++)  
    {  
     if (j>=volume[i])best[i][j]=max(best[i-1][j],best[i-1][j-volume[i]]+value[i]);  
     else best[i][j]=best[i-1][j];  
    }  
    cout<<best[N][V]<<endl;  
 }  
 return 0;  
}  
虽然这样时间是优化到极限了,但空间还有优化的余地,所以自然而然还有一种是用一维数组来写,这需要状态转移方程的第二个循环反向遍历才行,这个会在下一章节加以介绍。(我也是研究了许久才明白。。。。说白了还是基础不扎实,刚接触算法的缘故。。。。)






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值