实验二 动态规划算法

这篇博客介绍了如何使用动态规划解决经典的0/1背包问题,给出了物品的重量和价值,以及背包的最大容量。通过动态规划表格,确定如何选择物品以最大化背包中物品的总价值。代码示例展示了如何初始化和填充动态规划矩阵,以及如何根据矩阵找到最优解。
摘要由CSDN通过智能技术生成

本关任务:给定N个物品和一个背包,背包的容量为W, 假设背包容量范围在[0,15],第i个物品对应的体积和价值分别为W[i]和v[i]。
各种物品的价值和重量如下:
物品编号 1 2 3 4 5
重量W 3 4 7 8 9
价值V 4 5 10 11 13
求: 如何选择装入背包的物品,使得装入背包的物品的总价值为最大。

相关知识

为了完成本关任务,你需要掌握:

1.动态规划原理的方法;

2.0/1背包问题。

/*
本关任务:给定N个物品和一个背包,背包的容量为W, 假设背包容量范围在[0,15],第i个物品对应的体积和价值分别为W[i]和v[i]。各种物品的价值和重量如下:
     物品编号   1   2   3   4   5
      重量W    3   4   7   8   9
      价值V    4   5   10  11  13
求: 如何选择装入背包的物品,使得装入背包的物品的总价值为最大。

*/
#include <stdio.h>
#include <stdlib.h>
// #define max(a,b) \
//    ({ __typeof__ (a) _a = (a); \
//        __typeof__ (b) _b = (b); \
//      _a > _b ? _a : _b; })
#define N 5//goods num
#define BAGW 15
int main( void )
{
    int w[N+1],v[N+1];
    w[0]=0;
    v[0]=0;
    for (int i = 1; i < N+1; i++)//get goods's wight and value
    {
        scanf("%d %d",&w[i],&v[i]);
    }
//    for (int i = 0; i < N+1; i++)//get goods's wight and value
//    {
//        printf("%d %d",w[i],v[i]);
//        printf("\n");
//    }
    printf("w v 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n");
//    int cnt = 0;
//    for (int i = 0; i < 16; i++)//假设背包容量范围在[0,15]
//    {

//    int bagW = BAGW;

//    int **dp;
//    dp =  (int**)malloc(sizeof(int*)*(N+1));//line
//    for (int k = 0; k < N+1; k++)//column
//    {
//        *(dp+k)  = (int*)malloc(sizeof(int)*(BAGW+1));
        //table of dp
//        for(int j=0;j<BAGW+1;j++){
//            dp[k][j]=0;
//        }
//    }
    int dp[N+1][BAGW+1]={{0}};

    for (int k = 1; k <= N; k++)
    {
        for (int j =1; j <= BAGW; j++)
        {
            if(j < w[k])
                //包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,
                //即V(i,j)=V(i-1,j)
            {
                dp[k][j]=dp[k-1][j];
//                printf("dp[%d][%d]=%d\n",k,j,dp[k][j]);
            }else
                //还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,
                //所以在装与不装之间选择最优的一个,即V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)}。
                //V(i-1,j-w(i))+v(i) 表示装了第i个商品,背包容量减少w(i),但价值增加了v(i);
            {
                if(dp[k-1][j]>dp[k-1][j-w[k]]+v[k]){
                dp[k][j]=dp[k-1][j];
                }else{
                    dp[k][j]=dp[k-1][j-w[k]]+v[k];
                }
                
//                printf("dp[%d][%d]=%d\n",k,j,dp[k][j]);
            }
        }
    }

    for (int k = 0; k < N+1; k++)//动态规划表的输出
    {
        printf("%d %d ",w[k],v[k]);
        for (int j = 0; j < BAGW+1; j++)
        {
            if(j==BAGW)
            {
                printf("%d",dp[k][j]);
                continue;
            }
            printf("%d ",dp[k][j]);
        }
        printf("\n");
    }

    for (int k = 0; k <N+1; k++)//free two demens space
    {
        free(*(dp+k));
    }
//    }
    return  0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值