在上一篇文章我们讲到我们用递归去实现01背包问题的挑选。那我们是用建立了递归函数bag(n,cap);而我们可以发现,这个函数有两个参数,是不是可以把它转化成我们的二维数组呢?说干就干,我们来试试。
int bag[n][cap];
我们知道递归目的是要求bag(n,cap),而利用的是递归求前面的数据,那我们只要把数组中前面数据求出来,就可以顺着推导到bag[n][cap]。
首先还是边界,这里我们用i,j变量遍历n,cap
只有一个物品时:
if(n==1)
if(cap>=w[0])
return v[0];
else return 0;
改写成:
if(i==1)
if(j>=w[0])
bag[i][j]=v[0];
else bag[i][j]=0;
袋子容量不够时:
if(cap<w[n-1])
return bag(n-1,cap);
改写成:
if(j<w[i-1])
bag[i][j]=bag[i-1][j];
那剩下的就是循环,以及迭代公式了,公式还是和之前一样:
return max(bag(n-1,cap),(bag(n-1,cap-w[n-1])+v[n-1]));
改写成: bag[i][j]= max( bag[i-1][j], (bag[i-1][j-w[i-1]+v[i-1] );
代码:
#include<stdio.h>
#include<time.h>
#define max(x,y) x>y?x:y
int v[3]={4,5,8};
int w[3]={4,5,7};
/*
int bag(int n,int cap)
{
if(n==1)
if(cap>=w[0])
return v[0];
else return 0;
if(cap<w[n-1])
return bag(n-1,cap);
return max(bag(n-1,cap),(bag(n-1,cap-w[n-1])+v[n-1]));
}*/
int main()
{ int n=3,cap=10,bag[3][10],i,j;
for(i=0;i<n;i++)
for(j=0;j<cap;j++)
if(i==1)
if(j>=w[0])
bag[i][j]=v[0];
else bag[i][j]=0;
else if(j<w[i-1])
bag[i][j]=bag[i-1][j];
else bag[i][j]= max( bag[i-1][j], (bag[i-1][j-w[i-1]]+v[i-1]));
printf("%d",bag[2][9]);
return 0;
}
运行截图:
已修改部分错误内容,原return 0以修改。
袋子容量不够时:
if(cap<w[n-1])
return bag(n-1,cap);
改写成:
if(j<w[i-1])
bag[i][j]=bag[i-1][j];