动态规划三--------点击此处
动态规划二--------点击此处
动态规划一--------点击此处

动态规划(dp)核心原理是分类加法原理和分布乘法原理。,在当状态的上一个或几个状态中找出最优解求得当前状态,而对于前一个或者几个状态采用同样的方法直到求出边界状态。

一定要满足下面几点:
1.具有相同子问题。可以分解出几个子问题。
2.满足最优化原理(最优子结构)一个最优决策。
3.具有无后效性:要求每一个问题的决策不能够对解决其它未来的问题产生影响,如果产生影响那么无法保证其最优性。

下面以2道有一定难度的题目进行讲解。

目录

  • 加括号求最大值
  • 猴子快乐

加括号求最大值

题目描述:给你一个表达式,你可以通过在不同的地方添加括号从而改变式子的结果。比如1 + 2 * 3,如果是(1+2)3结果是9,如果是1+23,结果是7,现在给你一个这样的式子,保证只有乘法和加法,但是也许会出现负数,求出这个式子通过不同的加括号方式,所能求得的最大结果。
输入:
多组数据,每组数据第一行给出一个整数N(2<=N<=100),是所给式子的整数个数,下面包含表达式,所有整数和符号之间都会相隔一个空格。
输出:
对于每组测试数据输出一个给出式子能算出的最大值。

样式输入:
4
1 + 2 * 3 + -1
样式输出:
8

我们怎么思考这个问题呢?以下均是我个人理解。
首先肯定要遍历从第一个数到第n个数的,那么设一个函数Max(i,j)表示第i个整数到第j个整数加上一层括号的最大值。那么其实我们需要解决的就是子式的最大值了。我们知道正数乘正数表达式是最大的,所以有效利用好这个乘号。
当然题目要求只有加法和乘法,那其实稍微简单了,我们只要选出乘号,并标记为1,那么加号自然就是0了。注意到,有n个数,那么必然有n-1个符号,那么我们将符号和数字的顺序绑定一起,把初始工作完成。
那么有个疑惑,就是如何保存已搜索的信息,那么设立一个结构体,里面要包含最大值和最小值,表示的就是第i个数到第j个数的情况,有人要问了为什么要保存最小值呢?便于更好地区分,其实加不加也无所谓。
那么子问题是什么呢,就是i到j的情况。通过设立一个中转变量来处理好括号的存在。如果前面小了继续向上推,直到这个中转变量到达了j处(就是最后的n)
下面附代码:

#include <iostream>
#include <cstdio>#define SUM 101
#define Max 100000000
#define Min -100000000using namespace std;int n,num[SUM],ope[SUM];//ope表示存放运算符,num存放数struct rem{int max;int min;
};rem result[SUM][SUM];rem cmp(int a1,int a2,int a3,int a4){int max=Min,min=Max,temp=0;if((temp=a1*a3)>max) max=temp;if(temp<min) min=temp;if((temp=a1*a4)>max) max=temp;if(temp<min) min=temp;if((temp=a2*a3)>max) max=temp;if(temp<min) min=temp;if((temp=a2*a4)>max) max=temp;if(temp<min) min=temp;rem p;p.max=max;p.min=min;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              return p;
}//max[i][j]表示第i个整数到第j个整数加上括号得到的最大值,这样最终结果就是MAX[1][n]
rem MAX(int i,int j){if(i==j){result[i][j].max=num[i];result[i][j].min=num[i];return result[i][j];}if(i<j){if(result[i][j].max!=Min){return result[i][j];}else{for(int t=i;t<j;t++){rem tempa=MAX(i,t);rem tempb=MAX(t+1,j);if(ope[t]==1){rem c=cmp(tempa.max,tempa.min,tempb.max,tempb.min);if(c.max>result[i][j].max) result[i][j].max=c.max;if(c.min<result[i][j].min) result[i][j].min=c.min;}else{int mm=tempa.max+tempb.max;if(mm>result[i][j].max) result[i][j].max=mm;int mi=tempa.min+tempb.min;if(mi<result[i][j].min) result[i][j].min=mi;}}return result[i][j];}}//return result[i][j];
}int main(){int i,j;char ch;while(cin>>n){for(i=1;i<n;i++){cin>>num[i];getchar();cin>>ch;if(ch=='*') ope[i]=1;else ope[i]=0;}cin>>num[n];for(i=0;i<=n;i++){for(j=0;j<=n;j++){result[i][j].max=Min;result[i][j].min=Max;}}int max=MAX(1,n).max;cout<<max<<endl;}return 0;
}

猴子快乐

题目描述:在hphp还没有电脑的时候,手机是她唯一的娱乐工具,最喜欢玩的游戏就是猴子,猴子的行动范围是在n(n<=100)根水平排列的柱子的底端上,并且以坐虫子为快乐。每坐到一个虫子他就快乐一点。可是他的快乐是有极限的,因为他只能水平的在相邻的柱子间移动,并且移动一次时间是1s,如果在时间t(0<=t<=10000)猴子刚好在柱子m(1<=m<=n)上并且此时m上恰好会出现一只虫子,那么猴子就可以坐到它了。现在猴子最初(0s)在1号柱子上,在t时间m柱子上是否能有虫子以一个矩阵给出。猴子想要最快乐,你是否能够帮助它呢~
输入:
多组测试数据,每组测试数据首先给出整数n,t (0<n<=100,0<=t<=10000)占一行。n表示总共有多少柱子,t表示游戏结束的时间,t时间猴子就不可以再坐虫子咯。接下来有n行,每行有t个整数(0或1)T0,T2…Tt-1。第i行第j个数字表示第i个柱子在j时间是否有虫子出现。
输出:
对于每组测试数据输出一个整数,表示猴子快乐的最大点数。

样式输入:
3 4
0 1 0 1
1 0 0 1
1 1 1 1
3 4
1 0 1 0
1 1 1 0
1 1 1 1
1 5
1 0 1 0 1
样式输出:
2
2
3

分析:用max[i][j]表示在第i时间在第j个柱子上时能得到的最大的幸福值;grid[i][j]表示第i时间第j柱子是否有虫子。那么mx[i][j]=Max(mx[i-1][j-1],m[i-1[j],mx[i-1][j+1])+grid[j][i].边界问题要特别注意。

#include <iostream>#define MAX 1<<29
#define N 100
#define T 10100using namespace std;int mx[T][N],grid[N][T];int n,limt;int Max(int a,int b,int c){int z;z=(a>b)?a:b;return z>c?z:c;
}int main(){while(cin>>n>>limt){for(int i=1;i<=n;i++){for(int j=0;j<limt;j++){cin>>grid[i][j];}}for(int i=1;i<=n;i++){for(int j=0;j<limt;j++){mx[j][i]=-MAX;}}mx[0][1]=grid[1][0];for(int i=1;i<limt;i++){for(int j=1;j<=n&&j<=i+1;j++){int a=-MAX,b=-MAX,c=-MAX;if(j>1) a=mx[i-1][j-1];b=mx[i-1][j];if(j<n) c=mx[i-1][j+1];mx[i][j]=Max(a,b,c)+grid[j][i];}}int mxmx=0;for(int i=1;i<=n;i++){if(mx[limt-1][i]>mxmx) mxmx=mx[limt-1][i];}cout<<mxmx<<endl;}return 0;
}

【算法专项】动态规划专项四相关推荐

  1. 算法导论-动态规划(dynamic programming)

    动态规划:通过组合子问题的解来解决整个问题. 动态规划的四个步骤: 1)描述最优解的结构: 2)递归定义最优解的值: 3)按自低向上的方式计算最优解的值(首先找到子问题的最优解,解决子问题,最后找到问 ...

  2. 五大经典算法之动态规划

    一.概念起源   动态规划,又名DP算法(取自其Dynamic Programming的缩写),最初是运筹学的一个分支,是用来求解决策过程最优化的数学方法. 二.基本思想   把 多阶段过程 转化为一 ...

  3. Java入门算法(动态规划篇2:01背包精讲)

    本专栏已参加蓄力计划,感谢读者支持❤ 往期文章 一. Java入门算法(贪心篇)丨蓄力计划 二. Java入门算法(暴力篇)丨蓄力计划 三. Java入门算法(排序篇)丨蓄力计划 四. Java入门算 ...

  4. NOI入门级:算法之动态规划

    糖糖讲动态规划算法,找零钱完全背包问题,LeetCode 322 糖糖讲动态规划算法,找零钱完全背包问题,LeetCode 322_哔哩哔哩_bilibili 程序员面试再也不怕动态规划了,看动画,学 ...

  5. 算法:动态规划窃贼问题C语言实现

    算法:动态规划窃贼问题C语言实现 目录 算法:动态规划窃贼问题C语言实现 第一章 问题描述 1.1问题描述 第二章 算法思想及算法设计分析 2.1算法思想 2.2设计算法 2.3算法分析 2.4填表结 ...

  6. 【算法】动态规划 ① ( 动态规划简介 | 自底向上的动态规划示例 | 自顶向下的动态规划示例 )

    文章目录 一.动态规划简介 二.自底向上的动态规划示例 1.原理分析 2.算法设计 3.代码示例 三.自顶向下的动态规划示例 1.算法设计 2.代码示例 一.动态规划简介 动态规划 , 英文名称 Dy ...

  7. 基于MVS的三维重建算法学习笔记(四)— 立体匹配经典算法Semi-Global Matching(SGM)论文翻译及要点解读

    基于MVS的三维重建算法学习笔记(四)- 立体匹配经典算法Semi-Global Matching(SGM)论文翻译及要点解读 声明 SGM概述 Cost Calculation(像素代价计算)--M ...

  8. 数据结构与算法学习⑥(动态规划 题解 背包和打家劫舍问题)

    数据结构与算法学习⑥(动态规划 动态规划 1.初识动态规划 1.1.从贪心说起 1.1.1.贪心的特点 1.1.2.贪心的局限性 1.1.3.贪心失效后怎么办 1.1.4.从最优化问题到递归 1.2. ...

  9. 趣学算法系列-动态规划

    趣学算法系列-动态规划 声明:本系列为趣学算法一书学习总结内容,在此推荐大家看这本算法书籍作为算法入门, 原作者博客链接,本书暂无免费电子版资源,请大家支持正版,更多实例分析请查看原书内容 第四章 动 ...

  10. Hash算法解决冲突的四种方法

    Hash算法解决冲突的四种方法 参考文章: (1)Hash算法解决冲突的四种方法 (2)https://www.cnblogs.com/lyfstorm/p/11044468.html 备忘一下.

最新文章

  1. 架构周报:微信后台系统的演进之路
  2. 无限极分类不知pid_PHP实现无限极分类
  3. 在Python中操纵json数据的最佳方式
  4. 机器学习学习吴恩达逻辑回归_机器学习基础:逻辑回归
  5. java 扫描自定义注解_利用spring 自定义注解扫描 找出使用自定义注解的类
  6. 学习——AQS工作原理分析
  7. 标准C程序设计七---121
  8. python爬取知乎用户信息_python爬取知乎用户总结
  9. Javashop 7.0 支付成功以后库里面没有记录问题
  10. Linux查 ssh端口号
  11. Linux下sz下载文件超过4G办法
  12. 循环经济升级推动产业升级发展建议
  13. whois php,域名whois php
  14. 〖Python接口自动化测试实战篇⑦〗- 接口抓包工具 Fiddler 的使用
  15. 微信商户号企业付款到零钱开通地址
  16. MT6575芯片原理图MT6575原理图及量产板
  17. 网络安全之防病毒网关
  18. 农夫 狼 羊 白菜 java,农夫、狼、羊、白菜(回溯法求解)
  19. 信息系统项目管理师-项目沟通管理
  20. mysql连接异常:The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zo

热门文章

  1. 计算机主机配置,电脑主机配置怎么选择 电脑主机配置选择技巧介绍【详解】...
  2. SpringBoot+Redis哨兵模式
  3. ReactNative系列之二十一仿微信发语音空消息
  4. 2021-11-03大数据学习日志——数据埋点+网络爬虫——requests 模块
  5. 弘辽科技:2021创业开网店如何?
  6. C++详解邻接矩阵与邻接表
  7. MySQL连表查询并统计
  8. 信息学奥赛一本通-2062【例1.3】电影票 题解
  9. 2022年好用又便宜蓝牙耳机推荐_平价学生党蓝牙耳机品牌
  10. 从0到1学数据库:Function函数