动态规划算法剖析

超详细!动态规划详解分析(典型例题分析和对比,附源码) 为啥要使用动态规划?什么时候使用动态规划?以下是我的一些理解和心得,如果你感兴趣,就接着往下看吧。 对您有帮助的话记得给我点个赞哟! 动态规划的基本思想 动态规划(Dynamic Programming,DP)算法通常用于求解某种具有最优性质的问题。在这类问题中,可能会有许多可行解,每一个解都对应一个值,我们希望找到具有最优值的解。 动态规划算法与分治法类似,其基本思想也是将待求解的问题分解成若干个子问题,先求解子问题,然后从这些子问题的解中 得到原有问题的解。与分治法不同的是,动态规划经分解后得到的子问题 阅读详情

最优化原理
   1951年美国数学家R.Bellman等人,根据一类多阶段问题的特点,把多阶段决策问题变换为一系列互相联系的单阶段问题,然后逐个加以解决。一些静态模型,只要人为地引进“时间”因素,分成时段,就可以转化成多阶段的动态模型,用动态规划方法去处理。与此同时,他提出了解决这类问题的“最优化原理”(Principle of optimality):
    “一个过程的最优决策具有这样的性质:即无论其初始状态和初始决策如何,其今后诸策略对以第一个决策所形成的状态作为初始状态的过程而言,必须构成最优策略”。简言之,一个最优策略的子策略,对于它的初态和终态而言也必是最优的。
    这个“最优化原理”如果用数学化一点的语言来描述的话,就是:假设为了解决某一优化问题,需要依次作出n个决策D1,D2,…,Dn,如若这个决策序列是最优的,对于任何一个整数k,1 < k < n,不论前面k个决策是怎样的,以后的最优决策只取决于由前面决策所确定的当前状态,即以后的决策Dk+1,Dk+2,…,Dn也是最优的。
    最优化原理是动态规划的基础。任何一个问题,如果失去了这个最优化原理的支持,就不可能用动态规划方法计算。能采用动态规划求解的问题都需要满足一定的条件: 
    (1) 问题中的状态必须满足最优化原理;
    (2) 问题中的状态必须满足无后效性。
    所谓的无后效性是指:“下一时刻的状态只与当前状态有关,而和当前状态之前的状态无关,当前的状态是对以往决策的总结”。

问题求解模式 
    动态规划所处理的问题是一个多阶段决策问题,一般由初始状态开始,通过对中间阶段决策的选择,达到结束状态。这些决策形成了一个决策序列,同时确定了完成整个过程的一条活动路线(通常是求最优的活动路线)。如图所示。动态规划的设计都有着一定的模式,一般要经历以下几个步骤。

   初始状态→│决策1│→│决策2│→…→│决策n│→结束状态
     图1 动态规划决策过程示意图

    (1)划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。在划分阶段时,注意划分后的阶段一定要是有序的或者是可排序的,否则问题就无法求解。
    (2)确定状态和状态变量:将问题发展到各个阶段时所处于的各种客观情况用不同的状态表示出来。当然,状态的选择要满足无后效性。
    (3)确定决策并写出状态转移方程:因为决策和状态转移有着天然的联系,状态转移就是根据上一阶段的状态和决策来导出本阶段的状态。所以如果确定了决策,状态转移方程也就可写出。但事实上常常是反过来做,根据相邻两段各状态之间的关系来确定决策。
    (4)寻找边界条件:给出的状态转移方程是一个递推式,需要一个递推的终止条件或边界条件。

算法实现
    动态规划的主要难点在于理论上的设计,也就是上面4个步骤的确定,一旦设计完成,实现部分就会非常简单。使用动态规划求解问题,最重要的就是确定动态规划三要素:问题的阶段,每个阶段的状态以及从前一个阶段转化到后一个阶段之间的递推关系。递推关系必须是从次小的问题开始到较大的问题之间的转化,从这个角度来说,动态规划往往可以用递归程序来实现,不过因为递推可以充分利用前面保存的子问题的解来减少重复计算,所以对于大规模问题来说,有递归不可比拟的优势,这也是动态规划算法的核心之处。确定了动态规划的这三要素,整个求解过程就可以用一个最优决策表来描述,最优决策表是一个二维表,其中行表示决策的阶段,列表示问题状态,表格需要填写的数据一般对应此问题的在某个阶段某个状态下的最优值(如最短路径,最长公共子序列,最大价值等),填表的过程就是根据递推关系,从1行1列开始,以行或者列优先的顺序,依次填写表格,最后根据整个表格的数据通过简单的取舍或者运算求得问题的最优解。下面分别以求解最大化投资回报问题和最长公共子序列问题为例阐述用动态规划算法求解问题的一般思路。

1. 最大化投资回报问题:某人有一定的资金用来购买不同面额的债卷,不同面额债卷的年收益是不同的,求给定资金,年限以及债卷面额、收益的情况下怎样购买才能使此人获得最大投资回报。
    程序输入约定:第一行第一列表示资金(1000的倍数)总量,第二列表示投资年限;第二行表示债卷面额总数;从第三行开始每行表示一种债卷,占用两列,前一列表示债卷面额,后一列表示其年收益,如下输入实例,
10000 1
2
4000 400
3000 250
程序实现如下,注释几乎说明了一切,所以不再另外分析。
/// 此数组是算法的关键存储结构,用来存储不同阶段各种债卷
/// 组合下对应可获取的最大利息。
int saifa[80005];

/// 此函数用于计算当前债卷在不同购买额下的最优利息情况,
/// 注意此时的利息情况是基于上一次债卷的情况下计算得到的,
/// 也就是说当前利息最优是基于上一次利息最优的基础上计算出来的,
/// 这也正好体现了动态规划中“最优化原则”:不管前面的策略如何,
/// 此后的决策必须是基于当前状态(由上一次决策产生)的最优决策。
/*
    动态规划的求解过程一般都可以用一个最优决策表来描述,
    对于本程序,以示例输入为例,对于第一年,其最优决策表如下:
    0 1 2 3   4   5   6   7   8   9   10(*1000)  -- (1)
    0 0 0 0   400 400 400 400 800 800 800        -- (2)
    0 0 0 250 400 400 500 650 800 900 900        -- (3)
    (1) -- 表示首先选利息为400的债卷在对应资金下的最优利息。
    (2) -- 表示可用来购买债卷的资金。
    (3) -- 表示在已有状态下再选择利息为300的债卷在对应资金下的最优利息。
    注意上面表格,在求购买利息为300的债卷获得的最优收益的时候,
    参考了以前的最优状态,以3行8列的650为例,7(*1000)可以
    在以前购买了0张4000的债卷的基础上再2张3000的,也可以在以前购
    买了1张4000的基础上再买1张3000,经比较取其收益大的,这就是典
    型的动态规划中的当前最优状态计算。
    本程序中把上面的最优决策二维表用一个一维数组表示,值得借鉴。 
*/
void add(int a,int b)
{ cout << a << " " << b << endl; // for debug
 for(int i=0;i<=80000;i++)
 {
  if(i+a > 80000)
  {
   break;
  }

  if(saifa[i]+b > saifa[i+a]) // 累计同时购买多种债卷时的利息
  {
   saifa[i+a] = saifa[i] + b;
  }

  if(i<200) // for debug
   cout << i << "-" << saifa[i] << " ";
 }
 cout << endl; // for debug
}

int main(void)
{
 int n,d,money,year,pay,bond;
 int ii,i;

 scanf("%d",&n);
 for(ii=0;ii<n;ii++)
 {
  memset(saifa,0,sizeof(saifa));
  scanf("%d%d",&money,&year);
  scanf("%d",&d);

  for(i=0;i<d;i++)
  {
   scanf("%d%d",&pay,&bond);
   add(pay/1000,bond);
  }

  // 计算指定年限内最优组合的本金利息总额
  for(i=0;i<year;i++)
  { cout << saifa[money/1000] << " "; // for debug
   money += saifa[money/1000];
  }
  cout << endl; // for debug

  printf("%d/n",money);
 }

 return 0;
}
上述程序实现方法同样适合于背包问题,最优库存问题等,只是针对具体情况,最优决策表的表示和生成会有所不同。

2. 最长公共子串问题:一个给定序列的子序列是在该序列中删去若干元素后得到的序列。给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。最长公共子串就是求给定两个序列的一个最长公共子序列。例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列。
问题分析:
    给定两个序列A和B,称序列Z是A和B的公共子序列,是指Z同是A和B的子序列。问题要求已知两序列A和B的最长公共子序列。如采用列举A的所有子序列,并一一检查其是否又是B的子序列,并随时记录所发现的子序列,最终求出最长公共子序列。这种方法因耗时太多而不可取。
    考虑最长公共子序列问题如何分解成子问题,设A=“a0,a1,…,am-1”,B=“b0,b1,…,bm-1”,并Z=“z0,z1,…,zk-1”为它们的最长公共子序列。不难证明有以下性质:
(1) 如果am-1=bn-1,则zk-1=am-1=bn-1,且“z0,z1,…,zk-2”是“a0,a1,…,am-2”和“b0,b1,…,bn-2”的一个最长公共子序列;
(2) 如果am-1!=bn-1,则若zk-1!=am-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列;
(3) 如果am-1!=bn-1,则若zk-1!=bn-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列。
这样,在找A和B的公共子序列时,如有am-1=bn-1,则进一步解决一个子问题,找“a0,a1,…,am-2”和“b0,b1,…,bm-2”的一个 最长公共子序列;如果am-1!=bn-1,则要解决两个子问题,找出“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列 和找出“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列,再取两者中较长者作为A和B的最长公共子序列。
    为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法,具体说明如下。

定义c[i][j]为序列“a0,a1,…,ai-2”和“b0,b1,…,bj-1”的最长公共子序列的长度,计算c[i][j]可递归地表述如下:
(1)c[i][j] = 0                         如果i=0或j=0;
(2)c[i][j] = c[i-1][j-1]+1             如果i,j>0,且a[i-1] = b[j-1];
(3)c[i][j] = max{c[i][j-1], c[i-1][j]} 如果i,j>0,且a[i-1] != b[j-1]。
按此算式可写出计算两个序列的最长公共子序列的长度函数。由于c[i][j]的产生仅依赖于c[i-1][j-1]、c[i-1][j]和c[i][j-1],故可以从c[m][n]开始,跟踪c[i][j]的产生过程,逆向构造出最长公共子序列。细节见程序。

#include <stdio.h>
#include <string.h>

#define N 100

char a[N], b[N], str[N];
int c[N][N];

int lcs_len(char* a, char* b, int c[][N])
{
    int m = strlen(a), n = strlen(b), i, j;

    for( i=0; i<=m; i++ )    
        c[i][0]=0;
    for( i=0; i<=n; i++ )    
        c[0][i]=0;

    for( i=1; i<=m; i++ ) 
    {
        for( j=1; j<=n; j++ )
        {
            if (a[i-1]==b[j-1])
                c[i][j]=c[i-1][j-1]+1;
            else if (c[i-1][j]>=c[i][j-1])
                c[i][j]=c[i-1][j];
            else
                c[i][j]=c[i][j-1];
        }
    }

    return c[m][n];
}

char* build_lcs(char s[], char* a, char* b)
{
    int i = strlen(a), j = strlen(b);
    int k = lcs_len(a,b,c);
    s[k] = '/0';
    while( k>0 )
    {
        if (c[i][j]==c[i-1][j]) 
            i--;
        else if (c[i][j]==c[i][j-1]) 
            j--;
        else
        {
            s[--k]=a[i-1];
            i--; j--;
        }
    }

    return s;
}

void main()
{ 
    printf("Enter two string (length < %d) :/n",N);
    scanf("%s%s",a,b);
    printf("LCS=%s/n",build_lcs(str,a,b));
}

Copyright@戴维 2006.5  于北京 

数学建模优化类问题—动态规划 动态规划模型 阅读详情

相关推荐

深度剖析动态规划算法求解跳跃游戏

深度剖析动态规划算法求解跳跃游戏 题目描述:在一个N*N大小的棋盘中,每个格子都标有1到9当中的一个整数。游戏规则是,从棋盘的最左上角出发,最终到达最右下角。在此过程中,按照相应数值的大小可以向右或者向下移动,但是不能走出棋盘。关键在于,给定标有数值的棋盘时,判断出有没有达到终点的方法。如下如所示: 这个问题如何求解? 解法一:递归求解(采用穷举搜索法) 求解思路 从左上角起点开始搜...

梅森上校的博客 业精于勤荒于嬉,形成于思毁于随。 1106

动态规划算法解析

一、多阶段决策过程最优化问题 ——动态规划的基本模型 在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效 果。因此各个阶段决策的选取不能任意确定,它依赖于当前面临的状态,又影响以后的发展。当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过 程的一条活动路线。这种把一个问题看做是一个前后关联具有链状结构的多阶段过程就称为多阶段决策过程,这种问题称为多阶段决策最优化问题。     【例题1】

byrsongQQ的专栏 6689

用Linkboy玩转Arduino:3小时搞定智能倒车雷达(附仿真文件下载)

本文详细介绍了如何利用Linkboy图形化编程工具,在3小时内快速搭建一个基于Arduino的智能倒车雷达项目。通过仿真环境,初学者无需硬件即可学习超声波测距原理、报警逻辑设计,并完成从虚拟仿真到实体硬件的完整流程。文章提供了清晰的步骤、调试技巧及功能扩展思路,并附有仿真文件,是入门Arduino和智能硬件制作的绝佳实践指南。

weixin_29159441的博客 403

头歌 算法 实验七 动态规划

3)c[i][j]=max(c[i][j−1],c[i−1][j]) 如果i,j>0,且a[i−1]​=b[j−1]。由二维数组c的递归定义,c[i][j]的结果依赖于c[i−1][j−1],c[i−1][j]和c[i][j−1]。设长度为n的数组为(a[0],a[1],a[2],...,a[n−1]),则假定以a[j]结尾的数组序列的最长递增子序列长度为L(j),则L(j)=max(L(i))+1,i

Hakuuna的博客 3375

基于遗传算法的柔性作业车间调度(初始化以及编码策略)

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

菜鸡 8594

用例设计:滴滴打车从轿车到完成支付如何测?

滴滴打车全流程测试用例设计从业务场景覆盖、功能逻辑分解、异常流验证三个维度展开,系统化地构建了测试方案。首先,业务流主干场景被分解为叫车、行程中、支付结算三个阶段,每个阶段都设计了核心测试用例,包括正向和异常用例,如定位准确性、车型选择逻辑、路径偏移监控、费用实时计算、多支付方式兼容等。专项测试补充了状态机验证、资损防控测试和性能测试,确保系统在不同情况下的稳定性和安全性。测试数据策略采用等价类划分设计,实战技巧包括流量回放技术、混沌工程注入和计费沙盒验证,以提高测试的覆盖率和准确性。最终输出交付物包括流程

海姐软件测试的博客 1524

动态规划(Dynamic Programming)

我们清楚的知道使用分治算法来求解决斐波那契数列的效率惊人的低,其中的原因是,斐波那契数列分解成的两个子问题并不是独立的,它们之间有着非常多的交集,而在递归中,这些交集会被计算成百上千次,从而降低了算法的效率(这也是为什么分治算法要求子问题尽可能的不要相交)。如果观察斐波那契数列的通项公式,我们会发现数列的第n项只与它之前的两项有关,那么知道这两项也就得到了,这种从子问题出发,逐步得到原问题解的思想就是动态规划。

thdwx的博客 2550

【WB32库开发】第9章 TIM1高级定时器——输出多路PWM

PWM(Pulse Width Modulation)意为脉冲宽度调制,简称脉宽调制 。在工控行业,PWM信号可以用来调节电机转速、调节变频器以及BLDC电机驱动等;在LED照明行业,可以通过PWM来控制LED的亮暗变化;还可以通过PWM信号来控制无源蜂鸣器发出简单的声音等。 WB32也可输出PWM,需配置WB32上的定时器。 在WB32中有4个定时器,其中TIM1为高级定时器,TIMx(2-4)为通用定时器,这四个定时器均挂载在APB1总线上,每个定时器都可以输出4路PWM。 本章需要使用固件库TIM例程

北海村夫的博客 4637

【动态规划】深入动态规划:连续子结构的算法剖析

动态规划—连续子结构问题

2403_87459748的博客 6292

Cadence Allegro 17.4学习记录开始01-原理图Capture CIS 17.4

Orcad的学习记录

qq_31444421的博客 1万+

OCR模型轻量化新思路:用ONNX Runtime加速PP-OCRv4推理(附性能对比测试)

本文详细介绍了如何利用ONNX Runtime对PP-OCRv4模型进行轻量化部署与推理加速。通过模型导出优化、动态量化、线程绑定及内存复用等技巧,在树莓派、RK3588等边缘设备上实现了超过50%的性能提升,并显著降低了内存占用,为移动端OCR部署提供了完整的优化方案和实测数据对比。

weixin_29063979的博客 496

动态规划算法求解背包问题的全面剖析

对于0 - 1背包问题,状态转移方程为:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]),其中w[i]和v[i]分别表示第i个物品的重量和价值。例如,将dp[i][j]的更新改为dp[j] = max(dp[j], dp[j - w[i]] + v[i]),且j从capacity到w[i]逆序遍历。例如,在0 - 1背包问题中,当dp[i][j]小于当前已知的最大价值,且剩余物品的总价值加上dp[i][j]也小于最大价值时,可以剪枝。

2501_91302028的博客 643

基于转录逆转的药物重定向 GPS 模型

GPS是一个基于分子结构预测基因表达扰动的开源平台,由三个模块组成:RCL(在LINCS扰动数据上训练抗噪MLP)、GPS4Drugs(预测新化合物的基因表达谱并进行逆转评分)、MolSearch(基于MCTS的分子优化)。平台使用Morgan指纹和Gene Ontology注释作为特征输入,将基因表达扰动离散为三分类标签。训练数据来自LINCS Phase I的18,746个化合物和978个landmark基因,支持四细胞系独立训练,可用于药物重定向与化合物筛选。

听雨草堂 83

【动态规划】深入动态规划:简单多状态问题算法剖析

动态规划——多状态表问题

2403_87459748的博客 1638

破晓之光:GTK#框架让C# WinForm程序跨平台运行的终极指南

GTK#框架的出现,彻底打破了C# WinForm只能在Windows上运行的桎梏。

墨夶的博客 605

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

深度剖析动态规划算法:解题思路与练习技巧

对于计算 A_iA_{i + 1}\cdots A_j 的最优计算顺序,它的最优解包含了子问题 A_iA_{i + 1}\cdots A_k 和 A_{k + 1}A_{k + 2}\cdots A_j(i \leq k \lt j)的最优解。在练习动态规划时,从像爬楼梯这样的简单问题开始是很有效的方法。这个问题的状态很容易定义,设 dp[n] 表示爬到第 n 级台阶的方法数,状态转移方程为 dp[n] = dp[n - 1] + dp[n - 2],初始条件为 dp[1] = 1,dp[2] = 2。

mingzhuo5432的博客 387

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

动态规划算法的应用深度剖析12

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i])(当w[i] ≤ j时,比较放入和不放入该物品的价值,取较大值)。状态定义与0 - 1背包类似,但状态转移方程有所不同,为dp[i][j] = max(dp[i - 1][j], dp[i][j - w[i]] + v[i]),这里dp[i][j - w[i]]表示放入第i个物品后剩余容量j - w[i]的最大价值,因为物品可重复放入,所以是dp[i]而非dp[i - 1]。

2501_91651160的博客 1454

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

动态规划算法的应用深度剖析4

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i])(当w[i] ≤ j时,比较放入和不放入该物品的价值,取较大值)。状态定义与0 - 1背包类似,但状态转移方程有所不同,为dp[i][j] = max(dp[i - 1][j], dp[i][j - w[i]] + v[i]),这里dp[i][j - w[i]]表示放入第i个物品后剩余容量j - w[i]的最大价值,因为物品可重复放入,所以是dp[i]而非dp[i - 1]。

2501_91651160的博客 1233

动态规划算法的应用深度剖析7

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i])(当w[i] ≤ j时,比较放入和不放入该物品的价值,取较大值)。状态定义与0 - 1背包类似,但状态转移方程有所不同,为dp[i][j] = max(dp[i - 1][j], dp[i][j - w[i]] + v[i]),这里dp[i][j - w[i]]表示放入第i个物品后剩余容量j - w[i]的最大价值,因为物品可重复放入,所以是dp[i]而非dp[i - 1]。

2501_91651160的博客 591

动态规划算法的应用深度剖析1

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i])(当w[i] ≤ j时,比较放入和不放入该物品的价值,取较大值)。状态定义与0 - 1背包类似,但状态转移方程有所不同,为dp[i][j] = max(dp[i - 1][j], dp[i][j - w[i]] + v[i]),这里dp[i][j - w[i]]表示放入第i个物品后剩余容量j - w[i]的最大价值,因为物品可重复放入,所以是dp[i]而非dp[i - 1]。

2501_91651160的博客 597

动态规划算法的应用深度剖析13

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i])(当w[i] ≤ j时,比较放入和不放入该物品的价值,取较大值)。状态定义与0 - 1背包类似,但状态转移方程有所不同,为dp[i][j] = max(dp[i - 1][j], dp[i][j - w[i]] + v[i]),这里dp[i][j - w[i]]表示放入第i个物品后剩余容量j - w[i]的最大价值,因为物品可重复放入,所以是dp[i]而非dp[i - 1]。

2501_91651160的博客 700

动态规划算法的应用深度剖析8

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i])(当w[i] ≤ j时,比较放入和不放入该物品的价值,取较大值)。状态定义与0 - 1背包类似,但状态转移方程有所不同,为dp[i][j] = max(dp[i - 1][j], dp[i][j - w[i]] + v[i]),这里dp[i][j - w[i]]表示放入第i个物品后剩余容量j - w[i]的最大价值,因为物品可重复放入,所以是dp[i]而非dp[i - 1]。

2501_91651160的博客 752

动态规划算法的应用深度剖析6

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i])(当w[i] ≤ j时,比较放入和不放入该物品的价值,取较大值)。状态定义与0 - 1背包类似,但状态转移方程有所不同,为dp[i][j] = max(dp[i - 1][j], dp[i][j - w[i]] + v[i]),这里dp[i][j - w[i]]表示放入第i个物品后剩余容量j - w[i]的最大价值,因为物品可重复放入,所以是dp[i]而非dp[i - 1]。

2501_91651160的博客 610

动态规划算法的应用深度剖析3

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i])(当w[i] ≤ j时,比较放入和不放入该物品的价值,取较大值)。状态定义与0 - 1背包类似,但状态转移方程有所不同,为dp[i][j] = max(dp[i - 1][j], dp[i][j - w[i]] + v[i]),这里dp[i][j - w[i]]表示放入第i个物品后剩余容量j - w[i]的最大价值,因为物品可重复放入,所以是dp[i]而非dp[i - 1]。

2501_91651160的博客 585
上一篇: 排列组合问题的通用算法
下一篇: C/C++中的内存对齐
sharpdew
博客等级 码龄23年 76粉丝 35原创
评论 11
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值