动态规划算法

动态规划:

动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。 [1] 动态规划算法的基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。

通常 基于 一个递推公式 及一个或多个初始状态。当 前子问题的解将由上一次 子问题的解推出。

 

钢条问题:

给定一个长度为n英寸的钢条和一个价格表pi(i=1,2,3,...n),求能够使销售收益rn最大的切割方案
 

长度 i

1

2

3

4

5

6

7

8

9

10

价格p[i]

1

5

8

9

10

17

17

20

24

30

 

考虑n=4的时候

 

假如一个最优解把n段切成了k段(1<=k<=n),那么最优切割方案:
   i及下标表示第i段的长度,n为钢条的总长度。

最大收益:
    p及下标表示第i段的收益,r为钢条的总收益。

 

接下来对这个问题进行求解,我们先用普通的递归方法求解:

我们从钢条的左边切下长度为i的一段,只对右边剩下长度为n-i的一段继续进行切割,对左边的不再切割。

这样,当第一段长度为n的时候,收益为p[n],剩余长度为0,收益为0(这也是递归的基本问题),对应的总收益为p[n]。

当第一段长度为i的时候,收益为p[i],剩余长度为n-i,对应的总收益为p[i]加上剩余的n-i段再进行当第一段长度为i的时候,收益为p[i],剩余长度为n-i-i,....直到剩余长度为0,收益为0。
所以递归方程式为:

    pi就是就是p[i],可以看出每次都要进行从1到n的遍历。

 public static int UpDown2(int n, int[] p)
        {
            if (n == 0) return 0;

            int MaxPrice=0;
            for (int i = 1; i <=n; i++)
            {
                int temp = p[i] + UpDown2(n - i, p);
                if (temp>MaxPrice)
                {
                    MaxPrice = temp;
                }
            }
            return MaxPrice;
        }

  这个方法效率 是指数型的增加,r[9]和r[8] 都分解了r[7]

可以 加个 数组 来保存上次的值; 

每次执行 都去判断是否存在。

动态规划:

自顶向下的备忘录法

 static int UpDown(int n,int[] p,int[] result)
        {
            if (n==0){return 0;}
       
            int max = 0;
            if (result[n]!=0){return result[n];}
          
            for (int i = 1; i <=n ; i++)//i<n+1  最大值 就是n
            {   // 长度为n的 最大 收益
                int temp= p[i]+UpDown(n-i,p,result);

                if (temp>max){ max = temp;}

            }
            result[n] = max; // 保存  下n的 结果
            return max;
        }

   上面的方法思想还不算是 动态规划思想

下面介绍另一种

自底向上

  static int UpDown2(int n, int[] p, int[] result)
        {
            for (int i = 1; i <= n; i++)
            {
                int tempMax = -1;
                for (int j = 1; j <= i; j++)// 遍历 1到 i  寻找最大子数组
                {
                    int temp = p[j] + result[i - j];
                    if (temp > tempMax)
                    {
                        tempMax = temp;
                    }
                }
                result[i] = tempMax;
            }
            return result[n];
        }

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值