两个简单的动态规划问题,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;
}
这两个还是比较简单的,但是我希望能从简单问题找出通用套路。如果大家有其他的更好的思路可以给我留言。
转载于:https://www.cnblogs.com/dylan9/p/8723474.html
两个简单的动态规划问题,0-1背包和最大不相邻数累加和,附递归c代码相关推荐
- 实验3 动态规划(0/1背包)
1.问题给定的已知 N种物品和一个背包,物品的种类为wi,价值为vi,背包容量为C 2.所求目标 如何选择装入背包的物品,使得物品的总价值最大 3.数学模型 4.最优质子结构分析 现将问题分为n个子问 ...
- 动态规划算法初步(6)——0/1 背包
动态规划算法初步(6) 例题五:0/1 背包(背包型) 题目: 一个旅行者有一个最多能装m公斤物品的背包,现在有n件物品,它们的重量分别是w1,w2,-,wn,它们的价值分别为c1,c2,-,cn.若 ...
- python 动态规划 数塔_数塔问题,简单的动态规划算法
/* 数塔问题: 9 12 15 10 6 8 2 18 9 5 19 7 10 4 16 有形如图所示的数塔,从顶部出发,在每一结点可以选择向左走或是向右走, 一直走到底层,要求找出一条路径,使路径 ...
- 【动态规划】0/1背包问题
问题 H: [动态规划]0/1背包问题 时间限制: 1 Sec 内存限制: 64 MB 提交: 152 解决: 95 [提交] [状态] [讨论版] [命题人:admin] 题目描述 张琪曼和李旭 ...
- 两个简单的Demo示例向读者展示Flash和ASP.NET交互原理以及过程
ASP.NET与FLASH交互学习了ASP.NET的基础知识之后,终于等到学习交互的时候了.请大家和我一起来进行让人激动的交互吧!本章我将用两个简单的Demo示例向读者展示Flash和ASP.NET交 ...
- 服务器存储满了进不去系统,解决PC常见问题 篇四十五:建议收藏!手贱升级进不去系统?两步简单恢复黑群晖!...
解决PC常见问题 篇四十五:建议收藏!手贱升级进不去系统?两步简单恢复黑群晖! 2021-07-19 16:40:32 47点赞 302收藏 15评论 创作立场声明:本文属于原创文章,无任何利益关系, ...
- 思科Cisco packet tracer的实验之两个简单网络连接
思科Cisco packet tracer的实验之两个简单网络连接 1.界面 1.一开始都是从简单的交换机和几台电脑开始的 A网络: IP:210.226.3.1 网关:210.226.3.1 子网掩 ...
- halcon颜色识别的两种简单方式
颜色识别的两种简单方式: 1.单通道方式: 原理:通过不同颜色在灰度图中的阈值范围不同来区分颜色(理论上这种方式不推荐,但在一定情况下适用) 材料: halcon代码: dev_close_windo ...
- 非标准化疾病诉求的简单分诊挑战赛2.0
非标准化疾病诉求的简单分诊挑战赛2.0 赛题名称:非标准化疾病诉求的简单分诊挑战赛2.0 举办方:好大夫 赛题链接:点击 Fork项目运行请使用选择V100/32GB的GPU环境,显存不够适当减少ba ...
最新文章
- 博士申请 | 日内瓦大学招收机器学习和计算机视觉博士生(年薪35万)
- 设计模式之工厂方法模式学习笔记
- 运维少年系列 python and cisco (1)
- Hadoop2调优(一):如何控制job的map任务和reduce任务的数量
- win7下安装python失败问题_win7下安装ipython失败
- Ztree 改 节点
- win7下载原型软件Axure
- 计算机性能测评实验原理,实验一 计算机性能测试.pdf
- NOI(OJ)编程基础篇
- [大学物理实验-4]弦上驻波实验
- esp8266 wifi库文件
- vb.net 设置默认打印机
- python柱状图标注均值标准差_OpenCV Python 图像矩阵的均值和标准差
- PC/UVa 题号: 110106/10033 Interpreter (解释器)题解 c语言版
- 游戏无法启动此程序因为计算机中丢失,无法启动此程序因为计算机中丢失*.dll 看完你就知道了...
- 人生是一场秋花的盛开
- freescale R10 ipu lib 分析 - ipu_device.c
- 【Java】浅谈Swing概况及简单窗口的构建
- 2016计算机考研经验,2016大连理工大学计算机考研经验(示例代码)
- webservice:(2)体验查询号码归属地demo
热门文章
- 如何屏蔽VS2013中的4996错误!
- C++11 的新特性
- springboot自动配置流程
- 将同一列的值用逗号分隔连接成一个字符串
- [Java] SpringMVC工作原理之四:MultipartResolver
- [Javascript] Deep Search nested tag element in DOM tree
- 关于团队建设,穆帅能教我们什么?
- 数据库密码加密 使用的是 druid加密
- js立即执行函数: (function ( ){...})( ) 与 (function ( ){...}( ))
- KindEditor富文本编辑器, 从客户端中检测到有潜在危险的 Request.Form 值