所谓滚动数组,目的在于优化空间,从上面的解法我们可以看到,状态转移矩阵使用的是一个N*V的数组,在求解的过程中,我们可以发现,当前状态只与前一状态的解有关,那么之前存储的状态信息已经无用了,可以舍弃的,我们只需要空间存储当前的状态和前一状态,所以只需使用2*V的空间,循环滚动使用,就可以达到跟N*V一样的效果。这是一个非常大的空间优化。
代码如下,我们可以在每轮内循环结束后输出当前状态的解,与上面使用二维数组输出的状态转移矩阵对比,会发现是一样的效果,重定向输出到文本有助加深理解。
#include
using namespace std;
int maxValue[2][201];
int weight[11];
int value[11];
int V, N;
void main()
{
int i,j, k;
scanf("%d %d",&V, &N);
for(i= 0; i < N; ++i)
{
scanf("%d%d",&weight[i],&value[i]);
}
for(i= 0; i < N; ++i)
{
for(j = 0; j <= V;++j)
{
if(i > 0)
{
k = i& 1;
maxValue[k][j] = maxValue[k^1][j];
if(j >=weight[i])
{
int tmp =maxValue[k^1][j-weight[i]] + value[i];
maxValue[k][j] = ( tmp >maxValue[k][j]) ? tmp : maxValue[k][j];
}
}else
{
if(j >=weight[0])
maxValue[0][j] =value[0];
}
}
}
printf("%d",maxValue[k][V]);
freopen("C:\\dp.txt","w",stdout);
for(i= 0; i <= 1; ++i)
{
for(j = 0; j <= V;++j)
{
printf("%d ",maxValue[i][j]);
}
printf("\n");
}
}
这种空间循环滚动使用的思想很有意思,类似的,大家熟悉的斐波那契数列,f(n) =f(n-1) +f(n-2),如果要求解f(1000),是不需要申请1000个大小的数组的,使用滚动数组只需申请3个空间f[3]就可以完成任务。
========================================