zoukankan      html  css  js  c++  java
  • 递归代码_01背包_动态规划

    递归的思路,代码也写成递归的结构,应更方便理解一些吧。

    关于是怎么递归的(也就是那个状态转移方程)大家都写公式,我写文字吧:

    所有候选物,要么拿,要么不拿,从后至前挨个考虑。

    不拿的话,能获得的价值和只拿前面那些一样,没挤掉前面那些的重量额度,也没增加价值。

    如果要拿的话,当前考虑的这个物品自然要占一部分重量,那么可供前面那些物品使用的重量总额就要被挤掉一些。这就要计算一下,在更少的重量额度下,前面那些物品最多能拿多少价值。这就递归了(问题简化了一点,因为待考虑的物品数量少了1个,重量额度也少了一些)。回头再加上当前这个的价值,就是拿当前这个所能获得的总价值。

    看看拿和不拿哪个划算。打完收工。

    补充1下,当前这个得能拿得下(即使前面一个都不拿)才需要考虑。

    补充2下,当问题足够简单后,就用不着继续递归了,比如只需要考虑1个东西和C容量时,显然够容量就拿,不够容量就不拿,犯不着继续绕。

    代码如下:

    重量,价值
    class PackItem
    {
    public int Weight{get;private set;}
    public int Value{get;private set;}
    public PackItem(int weight, int value)
    {
    Weight
    = weight;
    Value
    = value;
    }
    }

    算法代码, 输入背包容量以及一组候选物, 返回最多能装多少价值。(没记录和返回具体选了哪些东西)

    算法
    class DynamicProgramming
    {
    public static int ZeroOnePack(int capacity, PackItem[] items)
    {
    return ZeroOnePackCore(items, items.Length, capacity);
    }

    private static int ZeroOnePackCore(PackItem[] items, int count, int cap)
    {
    //不拿就没价值
    if (count == 0) { return 0; }

    //在cap容量限制下,只在前count-1个中拿,最多多少价值
    int noTake = ZeroOnePackCore(items, count - 1, cap);

    //当前考虑的这个是否装得下?
    if (items[count - 1].Weight <= cap)
    {
    //以减少前几个的容量配额为代价,拿了当前这个的话有多少总价值
    int take = ZeroOnePackCore(items, count - 1, cap - items[count - 1].Weight) + items[count - 1].Value;

    //看看减少前面的配额来拿当前这个是否划算
    if (noTake < take) { return take; }
    }
    return noTake;
    }
    }

    拿几个例子测试一下,跟踪跟踪,直观看看吧。

    代码
    PackItem[] items = {
    new PackItem(1,2),
    new PackItem(2,3),
    new PackItem(3,4),
    new PackItem(4,5),
    new PackItem(5,6)};
    var v
    = DynamicProgramming.ZeroOnePack(5, items);

    Console.WriteLine(v);
  • 相关阅读:
    监控体系(二)
    piwik安装部署
    smokeping安装部署
    监控体系(一)
    学习zabbix(九)
    学习zabbix(八)
    学习zabbix(七)
    学习zabbix(六)
    数据结构之树形结构
    数据结构之线性结构
  • 原文地址:https://www.cnblogs.com/robird/p/1935826.html
Copyright © 2011-2022 走看看