最近面试经常被问到动态规划,所以自己做了一个总结,希望能进行深入的理解然后尝试能不能找到通用的解决手段。我觉得动态规划思想好理解,难的是怎么找出全部并且合理的子问题和出口。

我一般把问题分为两类,一类是有两个变化值,对应的我们要设一个二维数组记录(比如背包问题,每一步不仅物品发生变化,背包容量也改变);一类是一个变化值,对应的我们只需设置一个一维数组(比如只有一个变量改变的最值问题)。

然后确定该问题的子问题,找出状态转移方程。这里有一个小技巧,一般都是从数组最后一个元素开始逐步向前递归(思考方式也就是从最后一个开始思考),然后找递归出口即可。

从0-1背包问题说起:

一个背包总容量为W, 现在有N个物品, 第i个物品容量为w[i], 价值为v[i], 物品只能取或不取,现在往背包里面装东西, 怎样装才能使背包内物品总价值最大?

首先我们看到每一次选取,物品个数和背包容量都会发生变化,所以考虑设一个二维数组B[i][j],表示i个物品和容量为j的背包的问题,然后找它的子问题:

1 第i个体积太大,放不进去 W不变,i变为i-1。问题转化为i-1个物品和容量为W背包的问题

2 第i个体积不大,可以放进去

  (1)放进去    W变为W-w[i],i变为i-1 问题转化为i-1个物品和容量为W-w[i]背包的问题

  (2)不放进去 W不变 i变为i-1  问题转化为i-1个物品和容量为W背包的问题

除此以外应该没有其他可能了,所以我们找出了所有的子问题

写出c代码

#include<stdio.h>
#include <stdlib.h> int B[6][20];
int w[6] = { 0, 2, 3, 4, 5, 9 };
int v[6] = { 0, 3, 4, 5, 8, 10 }; int bag(int n, int W){
if (n == 0 || W == 0){
return 0;
}
else{
if (w[n] > W){
return bag(n - 1, W);
}
else{
return (bag(n - 1, W - w[n]) + v[n]) > bag(n - 1, W) ? (bag(n - 1, W - w[n]) + v[n]) : bag(n - 1, W);
}
}
} int main()
{
printf("hello world!\n");
printf("%d", bag(6, 20));
system("pause");
return 0;
}

  

接下来再来一个一维数组的:

从一个序列中选出互不相邻的几个数,是它们的累加和最大。比如[3,2,1,9,4,2]最大的就是3+9+2=14

求解:

可以看到,每选一个数,这个序列就会改变一次(因为不能再选与被选数相邻的),不存在其他变量,所以我们设一个一维数组num[i],i表示长度为i的数组(也可以说最后元素下标为i的数组)能选出的最大累加和,设第i个的值为v[i]。

然后找它的子问题:

1 选择第i个  因为不能选择第i-1个数,所以问题转化为长度为i-2的数组+v[i]的子问题

2 不选择第i个,问题转化为长度为i-1的数组的子问题

我们只要找出两者最大即可

代码:

#include<stdio.h>
#include <stdlib.h> int v[6] = { 3, 2, 1, 9, 4, 2 }; int add(int *value,int N){
if (N == 0){
return 0;
}
else if (N == 1){
return value[0];
}
else{
return add(value, N - 1) > (add(value, N - 2) + value[N - 1]) ? add(value, N - 1):(add(value, N - 2) + value[N - 1]);
}
} int main()
{
printf("%d", add(v,6));
system("pause");
return 0;
}

  这两个还是比较简单的,但是我希望能从简单问题找出通用套路。如果大家有其他的更好的思路可以给我留言。

两个简单的动态规划问题,0-1背包和最大不相邻数累加和,附递归c代码的更多相关文章

  1. 两个简单的Loading

    置顶文章:<纯CSS打造银色MacBook Air(完整版)> 上一篇:<JavaScript并非"按值传递"> 作者主页:myvin 博主QQ:85139 ...

  2. 两种简单实现菜单高亮显示的JS类(转载)

    两种简单实现菜单高亮显示的JS类   近期在写一个博客管理后台的前端,涉及在同一页面两种高亮显示当前菜单的需求.记得当年写静态页时,为了实现高亮都是在每个页面加不同的样式,呵.高亮显示我觉得对于web ...

  3. 简单理解 OAuth 2.0 及资料收集,IdentityServer4 部分源码解析

    简单理解 OAuth 2.0 及资料收集,IdentityServer4 部分源码解析 虽然经常用 OAuth 2.0,但是原理却不曾了解,印象里觉得很简单,请求跳来跳去,今天看完相关介绍,就来捋一捋 ...

  4. 简单创建一个SpringCloud2021.0.3项目(四)

    目录 1. 项目说明 1. 版本 2. 用到组件 3. 功能 2. 上三篇教程 3. 日志处理 1. 创建日志公共模块 2. Eureka引入日志模块 4. 到此的功能代码 5. 注册中心换成naco ...

  5. 简单创建一个SpringCloud2021.0.3项目(三)

    目录 1. 项目说明 1. 版本 2. 用到组件 3. 功能 2. 上俩篇教程 3. Gateway集成sentinel,网关层做熔断降级 1. 超时熔断降级 2. 异常熔断 3. 集成sentine ...

  6. 简单创建一个SpringCloud2021.0.3项目(二)

    目录 1. 项目说明 1. 版本 2. 用到组件 3. 功能 2. 上一篇教程 3. 创建公共模块Common 4. 网关Gateway 1. 创建Security 2. Security登陆配置 3 ...

  7. 简单创建一个SpringCloud2021.0.3项目(一)

    目录 1. 项目说明 1. 版本 2. 用到组件 3. 功能 2. 新建父模块和注册中心 1. 新建父模块 2. 新建注册中心Eureka 3. 新建配置中心Config 4. 新建两个业务服务 1. ...

  8. 两个简单方法加速DataGridView

    两个简单方法加速DataGridView (2009-03-24 16:57:13) 转载▼ 标签: 杂谈 分类: .NET DataGridView虽然好用,但是如果数据量比较大的话就会出现性能的问 ...

  9. 【转】在Android Studio中下载Android SDK的两种方式(Android Studio3.0、windows)

    在Android Studio中下载Android SDK的两种方式(Android Studio3.0.windows) 方式一.设置HTTP Proxy1. 打开Settings2. 点击HTTP ...

随机推荐

  1. CentOS 7的安装

    一.引导系统之后 界面说明: Install CentOS 7 安装CentOS 7 Test this media & install CentOS  7 测试安装文件并安装CentOS  ...

  2. windows安装wget

    windows安装wget1. 下载wget-1.11.4-1-setup.exehttps://jaist.dl.sourceforge.net/project/gnuwin32/wget/1.11 ...

  3. HTML5 <iframe> 标签

    iframe 元素会创建包含另外一个文档的内联框架(即行内框架). 即页面中嵌入另外一个独立的页面使用iframe,熟悉src是嵌套的页面的路径地址,scrolling属性可以设置iframe的滚动条 ...

  4. day69

    昨日回顾: 1 路由层:  1简单配置  2无名分组  3有名分组  4反向解析--模板层,视图层  5路由分发  include  6名称空间   7伪静态 2 作业:  urlpatterns = ...

  5. jqgrid 加入右键菜单按钮管理

    除了在表格底部添加自定义按钮外,还可以通过设置右键菜单按钮来添加自定义事件.看下图: 如何实现以上功能? 1)引入ContextMenu插件 2)创建一个函数用于初始化右键菜单(本示例取名为 init ...

  6. 【LeetCode9】Palindrome Number★

    题目描述: 解题思路: 求回文数,并且要求不能使用额外的空间.思路很简单,算出x的倒置数reverse,比较reverse是否和x相等就行了. Java代码: public class LeetCod ...

  7. kettle学习笔记(五)——kettle输出步骤

    一.概述 数据库表: • 表输出 • 更新,删除,插入/更新 • 批量加载(mysql,oracle) • 数据同步 文件: • SQL 文件输出 • 文本文件输出 • XML 输出 • Excel ...

  8. Python实现随机读取文本N行数据

    工作中需要判断某个文本中的URL是否能正常访问,并且随机获取其中N行能正常访问的URL数据,我的思路是:读取文本每一行数据,用urlopen访问,将返回状态码为200的URL保存到一个列表,获得列表长 ...

  9. MAC下配置ssh让SourceTree通过秘钥访问远程仓库

    问题描述 由于TortoiseGit没有MAC版本,我们使用了SourceTree来替代. 在帮同事解决Mac下的Git的时候,碰到一个问题:SourceTree无法使用ssh方式提交代码,这是由于没 ...

  10. linux gz 解压缩

    Linux压缩保留源文件的方法:gzip –c filename > filename.gzLinux解压缩保留源文件的方法:gunzip –c filename.gz > filenam ...