C#动态规划之0-1背包问题

一、问题描述

二、求解

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace dpBagPro
{
    class Program
    {
        /*
         * 动态规划之0-1背包问题
         * 现给出4个物品,编号,重量,价值如下:
         * 编号  1  2  3  4 
         * 重量  2  3  4  5
         * 价值  3  4  5  6
         * 有个背包能容纳重量为8,求装入此四种物品的最大价值
         * 
         * 分析,先将题目给的信息存入数组
         * 重量w[5],来源于英语weight->重量,价值v[5],来源于英语value->价值,
         * 复杂问题简单化,第一波先分析前一个物品装入一个容量1的背包价值多少,
         * 装到容量为8的价值是多少,第二波分析前两个物品装入容量1价值多少,直到8
         * 手动列出表格,行代表第几个物品,列是背包容量,行,列前面都要加0,
         * 得到一个二维数组并手动填入自己计算的值(这是答案)
         * 最大价值二维数组,这个二维数组命名dp[i][j],来源于动态规划英语-dynamic Programming
         * dp第一个长度i是行数+1->物品数+1,第二个长度j是列数+1->背包容量+1,加的1是放0
         * 本题i 取值范围为[1,4],j取值范围是[1,8],第一个表示for循环初始值1,第二个表示小于等于4/8
         * dp[5][9]
         * 列出表格得到答案倒推公式可得,为了防止出错带回去公式再算几个验证
         * if(w[i]>j){   //w[i]表示第几号物品的重量,如w[1]=2,w[2]=3...
         * 物品i直接装不下,去看前面的物品吧
         * dp[i,j]=dp[i-1,j];
         * }else{
         * //装入物品i,物品i价值v[i]+上一个物品装剩余容量的背包最大价值
         * A=v[i]+dp[i-1][j-w[i]];
         * // 不装物品就返回看看上一个物品价值吧。
         * B=dp[i-1][j]
         * 
         * dp[i][j]=max(A,B)
         * }
         * 
         * 
         */
        public static int[,] dp = new int[5, 9];// 结果数组
        public static int[] w = new int[5] { 0, 2, 3, 4, 5 };// 物品重量数组
        public static int[] v = new int[5] { 0, 3, 4, 5, 6 };// 物品价值数组
        public static void Main(string[] args)
        {
            for (int i = 1; i <= 4; i++)
            {
                for (int j = i; j <= 8; j++)
                {
                    if (w[i] > j)
                    {   //w[i]表示第几号物品的重量,如w[1]=2,w[2]=3...
                        // 物品i直接装不下,去看前面的物品吧
                        dp[i, j] = dp[i - 1, j];
                    }
                    else
                    {
                        //装入物品i,物品i价值v[i]+上一个物品装剩余容量的背包最大价值
                        int A = v[i] + dp[i - 1, j - w[i]];
                        // 不装物品就返回看看上一个物品价值吧。
                        int B = dp[i - 1, j];
                        // 返回最大
                        dp[i, j] = max(A, B);
                    }
                }
            }
            // 输出最后结果
            Console.WriteLine(dp[4, 8]);
            Console.ReadLine();
        }
        // 比大小
        public static int max(int a, int b)
        {
            if (a > b)
            {
                return a;
            }
            else
            {
                return b;
            }
        }
    }
}


三、总结

1.搞了我两天啊,好家伙,看懂就不容易了,我数学真不太好。前面三角函数就是线性代数,背包问题是数学归纳。
2.共性就是先将问题简单化,搞子问题,抽出公式,大佬们一看一分析就得到了,我不行。
看了几篇文章和b站视频,我比较接受好的办法是,先自己列出二维数组求解答案,这个人自己算真不难,难得是找出共性得到公式,得到就好搞了,得到公式为了以防万一再填写一遍表格验证对错,两相验证。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值