0-1背包问题与动态规划的C/C++代码

引用博客 https://blog.csdn.net/stpeace/article/details/46700657

0-1背包问题: 一个小偷来出来活动了, 拿了一个背包, 最多可以装50斤的东西的小袋子。 他眼睛一亮, 发现了三件宝贝a, b, c. 其中a重10斤, 价值60元; b重20斤, 价值100元; c重30斤, 价值120元。 问: 在背包允许的范围内, 小偷最多能偷到多少钱?

本想写个递推公式, 可是这CSDN写公式不太方便, 所以还是算了。 一旦有了递推公式, 要计算值, 那是计算机的长项, 直接给出代码吧, 代码蕴含一切(50斤=5十斤, 以十斤为一个单位, 方便编程):


#include<iostream>
using namespace std;

#define N 8 // N件宝贝
#define V 10 // C是背包的总capacity

int main()
{
    int value[N + 1] = { 0, 120, 100, 60, 100, 160, 180, 20, 5 }; // 钱啊
    int weight[N + 1] = { 0, 3,  2,  1, 5, 4, 3, 3, 2 };    // 重量
    int f[N + 1][V + 1] = { 0 }; // f[i][j]表示在背包容量为j的情况下, 前i件宝贝的最大价值

    int i = 1;
    int j = 1;
    for (i = 1; i <= N; i++)
    {
        for (j = 1; j <= V; j++)
        {
            // 递推关系式出炉
            if ( j < weight[i] )  //j - weight[i]
            {
                f[i][j] = f[i - 1][j];
            }
            else
            {
                int x = f[i - 1][j];
                int y = f[i - 1][j - weight[i]] + value[i];
                f[i][j] = x < y ? y : x;
            }
        }
    }

    for (i = N; i >= 1; i--)
    {
        for (j = 1; j <= V; j++)
        {
            printf("%4d ", f[i][j]);
        }

        cout << endl;
    }


    getchar();
    return 0;
}

j 代表啥?(便利数组所使用的数 for (j = 1; j <= V; j++) )
weight[i] 0, 1, 2, 3如上所示
f[i][j]的意义
if (j < weight[i]), else的作用 判断当前所拥有容量与重量的差值
插值 < 0
f[i][j] = f[i - 1][j] 意义 此时包内容量为上轮容量及包内价值为上轮价值
插值 > 0
int x = f[i - 1][j]; 上轮容量及包内价值为上轮价值
int y = f[i - 1][j - weight[i]] + value[i]; 当 j = weight时,vaule[i], 当 j > weight时,上轮容量及包内价值为上轮价值 + value[i]
俩意义

此时f[i][j]的值更新的意义 通过比较x与y获取当前最优!

递推公式的思想就是 数列, 从a1, a2, a3, , , , , an,,所以才有一下这种情况

上轮的意思是,
i = 1(只能拿一个物品且为weight数组和value数组的第一个元素的值),
i = 2(只能拿两个个物品且为weight数组和value数组的第一个元素的值和第二个元素的值)
当当前所拥有容量与重量的差值 < 0时 通过f[i][j] = f[i - 1][j]; 获取上轮最优
当当前所拥有容量与重量的差值 >= 0是 通过int x = f[i - 1][j]; int y = f[i - 1][j - weight[i]] + value[i]; 获取当前最优!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值