浅谈动态规划(个人理解)

动态规划,是常规的解决问题的一种方法,能解决的问题具有子问题的性质,即将大问题化成小问题进行分析解决,动态规划最重要的无非两点:状态和状态转移方程。所谓状态,指的是动态规划在化成每一个小问题时的状态,而状态转移方程,则是动态规划的关键:即将大问题化成小问题的方程:每个小问题的最优解都可以由这个方程得到,而大问题的最优解则是建立在小问题的最优解的基础上,下面我将通过一道经典题目来方便理解动态规划。

经典动规问题之0-1背包问题:

小明在旅行时偶然碰见一些钻石(假设有n个),而他只有一个背包,这个背包具有最大能承受的重量W,这n个钻石都有价值v和重量w,显而易见,钻石不能分解,所以小明对每个钻石只能选择带或不带每个钻石,请问:小明最大能带的钻石的价值是多大?

分析:很明显,这是一个动态规划问题:因为它能分解成小问题最优解--每个钻石带或不带,因此,我们只需要比较带了当前钻石以后的价值和不带当前钻石的价值哪个大,再考虑带还是不带当前钻石:没错,这就是我们此题的状态。假设我们用m[i][j]来保存有i个物品,最大承受重量为j时的最大价值,w[i],v[i]表示第i个物品的重量和价值那么我们的1状态转移方程又上面得:m[i][j] = max(m[i - 1][j],m[i - 1][j - w[i]] + v[i] ),分别表示不带当前物品的的价值和带上当前物品的价值,两者取大则为问题最优解,而最有优解也可以化为这样的方程,从而求得最优解的最优解,则得到的一定是最优解,接下来再上代码,就很好理解了:

/*0-1背包问题*/
#include <stdio.h>
int m[1000],v[1000],sum[1000][1000];//m[i]为每一个物品的重量,v[i]为每一个物品的价值,sum[i]用来存放背包可存放的最大价值

int max(int a,int b)
{
   return (a > b ? a : b);
}
int main(void)
{
   int i,j,M,n;//M为背包能装的最大重量,n为可选择物品个数
   while (scanf ("%d%d",&n,&M) != EOF)//输入可选择的物品个数
   {
      for (i = 0;i < n;i++)
      {
         scanf ("%d%d",&m[i],&v[i]);//输入每个物品的重量和价值
      }
      for (i = 0;i <= n;i++)
      {
         for (j = 0;j <= M;j++)
         {
            sum[i][j] = i == 0 ? 0 : sum[i - 1][j];//先将大问题表示为不带当前物品时的价值
            if(i > 0 && j >= m[i - 1])
            {
               sum[i][j] = max(sum[i][j],sum[i - 1][j - m[i - 1]] + v[i - 1]);//再将此时的价值和带上当前物品时的价值进行比较,两者取大
            }
         }
      }
      printf ("%d\n",sum[n][M]);//输出有n个物品,最大承受重量为M时的最大价值
   }

return 0;
}/*未完待续*/

时间: 2024-09-29 05:54:20

浅谈动态规划(个人理解)的相关文章

浅谈动态规划

动态规划算法(Dynamic Programming,简称 DP)似乎是一种很高深莫测的算法,你会在一些面试或算法书籍的高级技巧部分看到相关内容,什么状态转移方程,重叠子问题,最优子结构等高大上的词汇也可能让你望而却步. 而且,当你去看用动态规划解决某个问题的代码时,你会觉得这样解决问题竟然如此巧妙,但却难以理解,你可能惊讶于人家是怎么想到这种解法的. 实际上,动态规划是一种常见的「算法设计技巧」,并没有什么高深莫测,至于各种高大上的术语,那是吓唬别人用的,只要你亲自体验几把,这些名词的含义其实

浅谈我对动态规划的一点理解---大家准备好小板凳,我要开始吹牛皮了~~~

前言 作为一个退役狗跟大家扯这些东西,感觉确实有点...但是,针对网上没有一篇文章能够很详细的把动态规划问题说明的很清楚,我决定还是拿出我的全部家当,来跟大家分享我对动态规划的理解,我会尽可能的把所遇到的动态规划的问题都涵盖进去,博主退役多年,可能有些地方会讲的不完善,还望大家多多贡献出自己的宝贵建议,共同进步~~~ 概念 首先我们得知道动态规划是什么东东,百度百科上是这么说的,动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process

浅谈对Java中ThreadLocal类的理解

首先要明确:ThreadLocal不是一个多线程类,或者应该叫做线程局部变量.这从ThreadLocal的JDK定义中就可以看到 public class ThreadLocal<T>extends Object 可以看出ThreadLocal只是一个普普通通的类,并没有继承自Thread或实现Runnable接口. 同时也可以看到ThreadLocal使用了泛型,这样他就可以操作几乎任何类型的数据了.下面说JDK API代码时具体再说. 对此类,看看JDK API中的部分描述: 该类提供了线

【转载】李航博士的《浅谈我对机器学习的理解》 机器学习与自然语言处理

李航博士的<浅谈我对机器学习的理解> 机器学习与自然语言处理 [日期:2015-01-14] 来源:新浪长微博  作者: 李航 [字体:大 中 小] 算算时间,从开始到现在,做机器学习算法也将近八个月了.虽然还没有达到融会贯通的地步,但至少在熟悉了算法的流程后,我在算法的选择和创造能力上有了不小的提升.实话说,机器学习很难,非常难,要做到完全了解算法的流程.特点.实现方法,并在正确的数据面前选择正确的方法再进行优化得到最优效果,我觉得没有个八年十年的刻苦钻研是不可能的事情.其实整个人工智能范畴

37.浅谈js原型的理解

浅谈Js原型的理解 一.js中的原型毫无疑问一个难点,学习如果不深入很容易就晕了!    在参考了多方面的资料后,发现解释都太过专业,对于很多还没有接触过面向对象    语言的小白来说,有理解不了里面的专有名词!如果你没学过c++或者Java之类的更接触底层的语言,那就不要太深究,理解会用自然可以了,当接触到更多语言时慢慢的会理解越来越深刻! 下面我就举例分享一下prototype的概念!知道对于初学者知道这些就足够了! 分析一下,上面这个例子!我们可以知道 People的类型是一个对象!按照j

浅谈 Attention 机制的理解

什么是注意力机制? 注意力机制模仿了生物观察行为的内部过程,即一种将内部经验和外部感觉对齐从而增加部分区域的观察精细度的机制.例如人的视觉在处理一张图片时,会通过快速扫描全局图像,获得需要重点关注的目标区域,也就是注意力焦点.然后对这一区域投入更多的注意力资源,以获得更多所需要关注的目标的细节信息,并抑制其它无用信息. 图片来源:深度学习中的注意力机制,其中红色区域表示更关注的区域. Encoder-Decoder 框架 目前大多数的注意力模型都是依附在 Encoder-Decoder 框架下,

浅谈-对modbus的理解

浅谈-对modbus的理解 一.简介 Modbus由MODICON公司于1979年开发,是一种工业现场总线协议标准.1996年施耐德公司推出基于以太网TCP/IP的Modbus协议:ModbusTCP. Modbus协议是一项应用层报文传输协议,包括ASCII.RTU.TCP三种报文类型. 标准的Modbus协议物理层接口有RS232.RS422.RS485和以太网接口,采用master/slave方式通信. 二.报文 先来简单分析一条MODBUS报文,例如:01  06  00 01  00

浅谈元类(个人理解)

浅谈元类(个人理解) 我们知道在python中一切皆对象(object),那么所以有的对象都成了object的子类,那么object类又是由谁创建的呢? 实际上,能够创建类的类,叫元类.还有一个概念就是:元类创建了object类,同时又是object类的子类(这是什么鬼?我们就不去考虑这个逻辑了,已经完美解决了先有鸡还是先有蛋的问题了). 元类实际还是所有类的创建者,即使所有类(包括元类自己)都是object的子类,他们的关系如下: Interesting...... 原文地址:https://

10 浅谈 装饰器模式的理解与使用

在不改变现有类结构的情况下,为这个类添加一个新的功能,这就是装饰器模式 所属与结构型模式, 这种模式的特点是:需要创建一个装饰类来包装原有的类,并且提供额外的功能. 为了解决:平时使用继承的方式,会带入许多静态的方法,导致子类过度饱和,膨胀. 举例子:悟空拥有七十二变,不管它怎么变化,他的本质还是一只猴子,但是他又有变化后的一些本领(功能) 实现:装饰类包含原有类的实例对象,即可实现装饰器模式 开始: 定义一个形状的接口 //画图接口 public interface Shape { void