两个简单的动态规划问题,0-1背包和最大不相邻数累加和,附递归c代码
最近面试经常被问到动态规划,所以自己做了一个总结,希望能进行深入的理解然后尝试能不能找到通用的解决手段。我觉得动态规划思想好理解,难的是怎么找出全部并且合理的子问题和出口。
我一般把问题分为两类,一类是有两个变化值,对应的我们要设一个二维数组记录(比如背包问题,每一步不仅物品发生变化,背包容量也改变);一类是一个变化值,对应的我们只需设置一个一维数组(比如只有一个变量改变的最值问题)。
然后确定该问题的子问题,找出状态转移方程。这里有一个小技巧,一般都是从数组最后一个元素开始逐步向前递归(思考方式也就是从最后一个开始思考),然后找递归出口即可。
从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代码的更多相关文章
- 两个简单的Loading
置顶文章:<纯CSS打造银色MacBook Air(完整版)> 上一篇:<JavaScript并非"按值传递"> 作者主页:myvin 博主QQ:85139 ...
- 两种简单实现菜单高亮显示的JS类(转载)
两种简单实现菜单高亮显示的JS类 近期在写一个博客管理后台的前端,涉及在同一页面两种高亮显示当前菜单的需求.记得当年写静态页时,为了实现高亮都是在每个页面加不同的样式,呵.高亮显示我觉得对于web ...
- 简单理解 OAuth 2.0 及资料收集,IdentityServer4 部分源码解析
简单理解 OAuth 2.0 及资料收集,IdentityServer4 部分源码解析 虽然经常用 OAuth 2.0,但是原理却不曾了解,印象里觉得很简单,请求跳来跳去,今天看完相关介绍,就来捋一捋 ...
- 简单创建一个SpringCloud2021.0.3项目(四)
目录 1. 项目说明 1. 版本 2. 用到组件 3. 功能 2. 上三篇教程 3. 日志处理 1. 创建日志公共模块 2. Eureka引入日志模块 4. 到此的功能代码 5. 注册中心换成naco ...
- 简单创建一个SpringCloud2021.0.3项目(三)
目录 1. 项目说明 1. 版本 2. 用到组件 3. 功能 2. 上俩篇教程 3. Gateway集成sentinel,网关层做熔断降级 1. 超时熔断降级 2. 异常熔断 3. 集成sentine ...
- 简单创建一个SpringCloud2021.0.3项目(二)
目录 1. 项目说明 1. 版本 2. 用到组件 3. 功能 2. 上一篇教程 3. 创建公共模块Common 4. 网关Gateway 1. 创建Security 2. Security登陆配置 3 ...
- 简单创建一个SpringCloud2021.0.3项目(一)
目录 1. 项目说明 1. 版本 2. 用到组件 3. 功能 2. 新建父模块和注册中心 1. 新建父模块 2. 新建注册中心Eureka 3. 新建配置中心Config 4. 新建两个业务服务 1. ...
- 两个简单方法加速DataGridView
两个简单方法加速DataGridView (2009-03-24 16:57:13) 转载▼ 标签: 杂谈 分类: .NET DataGridView虽然好用,但是如果数据量比较大的话就会出现性能的问 ...
- 【转】在Android Studio中下载Android SDK的两种方式(Android Studio3.0、windows)
在Android Studio中下载Android SDK的两种方式(Android Studio3.0.windows) 方式一.设置HTTP Proxy1. 打开Settings2. 点击HTTP ...
随机推荐
- ORACLE RMAN备份及还原(转)
RMAN可以进行增量备份:数据库,表空间,数据文件 只有使用过的block可以被备份成backup set 表空间与数据文件对应关系:dba_data_files / v$datafile_heade ...
- 国家代号(CountryCode)与区号
Countries and Regions 国家或地区 国际域名缩写 电话代码 时差 Angola 安哥拉 AO -7 Afghanistan 阿富汗 AF 93 0 Albania 阿尔巴尼亚 AL ...
- ArcGIS中的坐标系统定义与投影转换方法
坐标系统是GIS数据重要的数学基础,用于表示地理要素.图像和观测结果的参照系统,坐标系统的定义能够保证地理数据在软件中正确的显示其位置.方向和距离,缺少坐标系统的GIS数据是不完善的,因此在ArcGI ...
- php5.6.40编译安装
yum install gcc bison bison-devel zlib-devel libmcrypt-devel mcrypt mhash-devel openssl-devel libxml ...
- Java并发(一)并发编程的挑战
目录 一.上下文切换 1. 多线程一定快吗 2. 测试上下文切换次数和时长 3. 如何减少上下文切换 4. 减少上下文切换实战 二.死锁 三.资源限制的挑战 四.本章小结 并发编程的目的是为了让程序运 ...
- linux 创建守护进程的相关知识
linux 创建守护进程的相关知识 http://www.114390.com/article/46410.htm linux 创建守护进程的相关知识,这篇文章主要介绍了linux 创建守护进程的相关 ...
- 曾经的UCOSii
首先记住一句话:实时操作系统,并非真的实时.操作系统必须有延时,一个系统执行好几个任务,实质是任务之间不停的切换,有延时才有切换任务的余地,如果没有.....应该都见识过卡机,任务切换不过来了 如果你 ...
- navicat 连接Oracle 报错:Cannot load OCI DLL, 126
1.64位win7 安装了oracle11g 使用Navicat for Oracle cannot load OCI DLL,126 解决方法:navicat 菜单中 -工具->选项-> ...
- 评定星级的前端显示js
五颗星的星级评定: 说明:假设是利用三种图片显示星级评定,即 1.满亮的星 2.半亮的星星 3.不亮的星星: 满分是5分:(此处当然可以作为一个参数可变 函数传入参数grade表示当前分值. func ...
- Mapreduce -- PageRank
PageRank 简单理解为网页排名,但是网页是根据什么排名的,接下来就简单介绍一下. 举例: 假设网页 A 的内容中有网页 B,C 和 D 的链接,并且 A 的 PageRank的值为0.25. 那 ...