算法学习(3):动态规划DP

  • 动态规划过程:

  每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。

  • 基本思想:

 将待求解的问题分解为若干个阶段,按顺序求解子阶段,前一子阶段的解,为后一子阶段的求解提供了有用的信息,存在一定的递推关系。即可以由(n1)的最优推导出n的最优。

  • 基本做法

  1.划分阶段,寻找从前一个阶段转化到后一个阶段之间的递推关系

  2.把子阶段信息保存在一个数组中(一维,二维或 三维)

  由于动态规划解决的问题多数有重叠子问题这个特点,为减少重复计算,对每一个子问题只解一次,将其不同阶段的不同状态保存在一个数组中。

  • 什么时候用动态规划

拿到一个问题时首先可以对其进行分类。对于可以拆分成子问题的,如果子问题之间相互独立,用分治法,如果子问题的前一个阶段和后一个阶段有递推关系,则适合用动态规划
  • 动态规划应用1--01背包问题

    有N件物品和一个容量为V的背包,第i件物品的体积是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

    解析:
    这是最基础的背包问题,特点是每种物品仅有一件,可以选择放或不放。用子问题定义状态,即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。其状态转移方程便是f[i][v] = max{f[i-1][v], f[i-1][v-c[i]]+w[i]},这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的,所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只关系前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,其价值为f[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。

    算法实现:

    #include<stdio.h>  
    #include<string.h>  
    #define N 1000  
    int f[N][N];  
      
    int main()  
    {  
        int w[N], c[N], i, j, n, v;  
        // 输入物品的个数;输入背包的体积  
        scanf_s("%d%d", &n, &v);  
        // 输入n种物品的价值;  
        for(i = 1; i <= n; i++)  
            scanf_s("%d", &w[i]);  
        // 输入n种物品的体积  
        for(i = 1; i <= n; i++)  
            scanf_s("%d", &c[i]);  
      
        // 初始化数组f的元素为0  
        memset(f, 0, sizeof(f));  
      
        for(i = 1; i <= n; i++)  
            for(j = 0; j <= v; j++)  
            {  
                // 如果当前物品的体积小于背包体积,  
                // 且当前物品的价值加上背包剩下的空间能放下的物品的价值大于上一次选择的最佳方案,则更新f[i][
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值