算法基础1.2:背包问题-代码实现

代码

动规类问题,通常可以采用循环或者递归方式来实现。当然所有的递归是否都可以用循环来实现?

#include "stdio.h"    
#include "stdlib.h"   
/*题设:4个物品,编号1,2,3,4,其价值分别为1,5,8,10,重量为2,3,4,7,总重量不超过10*/
#define TOTAL_NUM 4
#define TOTAL_WEIGHT 10

//为了简化边界处理条件判断的,将下标为0设置为初始值,这个方式屡试不爽
int v[TOTAL_NUM+1] = {0,1,5,8,10};
int w[TOTAL_NUM+1] = {0,2,3,4,7};           

int main(void)
{    
    int dp[TOTAL_NUM+1][TOTAL_WEIGHT+1] = {0}; //记录函数
    int trace[TOTAL_NUM+1][TOTAL_WEIGHT+1] = {0}; //标记函数
    int num = 0;
    int weight = 0;
    int repeat = 0;
    for(num = 1;num < TOTAL_NUM+ 1; num++)
    {
        for(weight = 1;weight < TOTAL_WEIGHT + 1; weight++)
        {
            if(w[num] <= weight) {
                repeat = weight/w[num];
                if(dp[num - 1][weight-w[num]]+repeat*v[num] >= dp[num - 1][weight]){
                    dp[num][weight] = dp[num - 1][weight-repeat*w[num]]+repeat*v[num];
                    trace[num][weight] = num;
                    continue;
                }
            }
            dp[num][weight] = dp[num - 1][weight];
            trace[num][weight]= trace[num - 1][weight];
        }
    }
    printf("\nprofit %d\n",dp[num-1][weight-1]);
}

时间复杂度

由于该问题只有两个变量前k个物品的最大质量为y,所以只需要2个for循环,所以复杂度为物品数目n最大质量w,即O(nw)。
关于动归的背包问题,也有为了减少空间开销而降二维数组压缩成以为动态数组的实现,但是我个人并不喜欢这种方式。原因是因为,我觉得只有最终结果或者最优值是毫无意义的,必须知道最优解是怎么来的,基于二维矩阵可以回溯出获得最优解的具体方案,而对于实际的生产而言,最优解的来源比最优解本身更重要。难道我告诉你从深圳去北京,最快需要10个小时,至于怎么走我不知道。。。这有意义吗?

你可能感兴趣的:(算法基础1.2:背包问题-代码实现)