0-1背包使用滚动数组压缩空间

来源:互联网 发布:淘宝汽车用品店排名 编辑:程序博客网 时间:2024/06/05 04:34

所谓滚动数组,目的在于优化空间,从上面的解法我们可以看到,状态转移矩阵使用的是一个N*V的数组,在求解的过程中,我们可以发现,当前状态只与前一状态的解有关,那么之前存储的状态信息已经无用了,可以舍弃的,我们只需要空间存储当前的状态和前一状态,所以只需使用2*V的空间,循环滚动使用,就可以达到跟N*V一样的效果。这是一个非常大的空间优化。


代码如下,我们可以在每轮内循环结束后输出当前状态的解,与上面使用二维数组输出的状态转移矩阵对比,会发现是一样的效果,重定向输出到文本有助加深理解。

#includeusing 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]就可以完成任务。


========================================

0 0
原创粉丝点击