我的背包递归解决方案可以改进吗?

Posted

技术标签:

【中文标题】我的背包递归解决方案可以改进吗?【英文标题】:Can my recursive solution for Knapsack be improved? 【发布时间】:2015-04-15 22:42:29 【问题描述】:

我正在尝试解决背包问题,这是我想出的递归解决方案。这可以做得更好吗?我想我需要通过检查我之前是否达到过这个状态来添加记忆。我需要为state[c_w][i] 添加状态是对的吗?

我故意没有使用动态编程,因为我知道它的递归关系,而是希望得到正确的递归。

#include <stdio.h>

int memoize[1000][1000];
int max(int a, int b)

        return a>b?a:b;


/* c_w-current weight of the container */ 
int max_profit_func(int *val, int *wt, int W, int c_w, int i, int size)

        int max_profit = 0;
        int j;

        /* if the current item is beyond the range then we have 0 profit*/
        if (i >= size)
                return 0;
        if (memoize[c_w][i] != -1)
                return memoize[c_w][i];
        /* get the profit with this index and if the profit is more than previous
         * than store it */
        for(j=i;j<size;j++) 
                int profit = 0;
                if (c_w+wt[j] <= W)
                        profit = val[j] + max_profit_func(val, wt, W, c_w+wt[j], j+1, size);
                max_profit = max(max_profit, profit);
        
        memoize[c_w][i] = max_profit;
        return max_profit;


int main(void) 
        int val[] = 3, 7, 2, 9;
        int wt[] = 2, 3, 4, 5;
        int W = 5;

        memset(memoize, -1, sizeof(int)*1000*1000);
        printf("%d\n", max_profit_func(val, wt, W, 0, 0, sizeof(wt)/sizeof(wt[0])));
        return 0;

【问题讨论】:

【参考方案1】:

你是对的。当您的函数正在解决问题时,它会一次又一次地重新计算相同的东西。

您需要沿着二维数组拖动,它将跟踪您已经解决了哪些对 (c_w, i) 以及结果是什么。这称为记忆(不是记忆):http://en.wikipedia.org/wiki/Memoization

【讨论】:

以上是关于我的背包递归解决方案可以改进吗?的主要内容,如果未能解决你的问题,请参考以下文章

带有零件集的背包递归解决方案

背包问题变体的递归关系?

在C中递归解决背包问题的麻烦

在 ruby​​ 中将数字转换为单词 - 改进我的递归解决方案

改进的背包算法

我的背包有问题吗