动态规划

P1387 最大正方形 |动态规划

北城以北 提交于 2019-12-04 07:58:12
题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长。 输入格式 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m个数字,用空格隔开,0或1. 输出格式 一个整数,最大正方形的边长 这题方法很多,n三方很容易想,但是有一个n方的动态规划很值得学习 #include<iostream> #include<cmath> using namespace std; int a[101][101],n,m,f[101][101],ans; int main() { cin>>n>>m; for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) { cin>>a[i][j]; if(a[i][j])f[i][j]=min(min(f[i][j-1],f[i-1][j]),f[i-1][j-1])+1; ans=max(ans,f[i][j]); } cout<<ans; } 来源: https://www.cnblogs.com/naruto-mzx/p/11846874.html

动态规划最短路径LintcodeNO110

試著忘記壹切 提交于 2019-12-04 07:06:19
动态规划最短路径LintcodeNO110 简单的dp题,没啥好说的... class Solution { public: /** * @param grid: a list of lists of integers * @return: An integer, minimizes the sum of all numbers along its path */ int minPathSum(vector<vector<int>> &grid) { // write your code here const int DP_N = 1000; const int DP_M = 1000; int n = grid.size(); int m = grid[0].size(); int i,j; int dp[DP_N][DP_M]; memset(dp,0,DP_N * DP_M); //初始化dp数组的值 dp[0][0] = grid[0][0]; for(int t=1;t<n;t++) { dp[t][0] = dp[t-1][0] + grid[t][0]; } for(int k=1;k<m;k++) { dp[0][k] = dp[0][k-1] + grid[0][k]; } //开始dp for(i=1;i<n;i++) { for(j=1;j<m;j++) {

动态规划

旧城冷巷雨未停 提交于 2019-12-04 06:58:27
62. 不同路径 63. 不同路径 II 121. 买卖股票的最佳时机 122. 买卖股票的最佳时机 II 53. 最大子序和 来源: https://www.cnblogs.com/ningff/p/11844933.html

动态规划(三)

旧街凉风 提交于 2019-12-04 02:17:51
10.Paths through the Hourglass,UVa10564 题意: 有一个沙漏,第一行有 \(n\) 个格子,第二行有 \(n-1\) 个格子 \(\cdots\cdots\) 最中间的行只有1个格子,然后它下面一行2个格子,再下面一行3个格子 \(\cdots\cdots\) 最后一行 \(n\) 个格子,如图 \(1-60\) 所示。你可以从第一行开始往下走,每次往下走一行,往左或往右走一列,但不能走出沙漏。你的目标是让沿途经过的所有整数之和恰好为一个给定的整数 \(S\) 。求出符合上述条件的路径条数和一条路径。 如果有多条路径,起点编号应尽量小(第一行格子从左到右编号为0~n-1)。如果仍有多解,移动序列( \(L\) 代表左, \(R\) 代表右)的字典序应最小。 分析: 简单的(对大佬来说)计数DP。 我们设状态 \(d[i][j][k]\) 表示从坐标为 \((i,j)\) 的点到达最后一层的和为 \(k\) 的方案数。 因为它只能往左下或者右下走,所以我们不难得出状态转移方程为: \[ d[i][j][k]=d[i+1][j][k-num[i][j]]+d[i+1][j+1][k-num[i][j] \] 注意以上方程只针对于行数编号大于等于 \(n\) 的时候,因为我们发现在前 \(n\) 行中的转移应该是 \[ d[i][j][k]=d[i

动态规划(四)

懵懂的女人 提交于 2019-12-04 02:17:42
\(1.String\) \(Painter,Chengdu\) \(2008,LA\) \(4394\) 题意: 给定两个长度相等,只有小写字母组成的字符串 \(s\) 和 \(t\) ,每步可以把 \(s\) 的一个连续子串“刷”称同一个字母,问至少需要多少不才能把 \(s\) 变成 \(t\) 。比如, \(s=bbbbbbb\) , \(t=aaabccb\) ,最少需要两步可实现将 \(s\) 变成 \(t\) : \(bbbbbbb->aaabbbb->aaabccb\) 。 分析: 一个套路的区间 \(DP\) ,和许多区间 \(DP\) 相似的是这里要设两个状态,一个是 \(f[i]\) 表示把 \(s\) 的前 \(i\) 个字符变成和 \(t\) 一样所需要的最小步数,一个是 \(dp[i][j]\) 表示的是把一个空串的 \([i,j]\) 区间变得和 \(t\) 一样所需要的最少步数。 贪心出一个性质,即每次刷一个串,都可以从头开始刷起,如果第一个字符相同,则从第二个开始刷,以此类推,而每次刷要么只刷一个字符,要么刷到另一个与目标串首字符相同的字符为止。 对于 \(dp\) 数组的转移,所以我们肯定只有当 \(t[i]==t[j]\) 的时候我们的粉刷才会是优秀的。 而对于 \(f\) 数组,我们当 \(s[i]=t[i]\) 的时候直接继承上一个状态即可

动态规划(二)

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-04 02:16:59
补充(一)中的部分 以下所有计算中都是将一个字符串当做 \(s[1]-s[n]\) 的 \(LCS\) (最长公共子序列) 我们设 \(d[i][j]\) 表示第一个串的前 \(i\) 位与第二个串的前 \(j\) 位的最长公共子序列的长度。 当 \(a[i]==b[j]\) 的时候, \(d[i][j]=d[i-1][j-1]+1\) 。 当 \(a[i]!=b[j]\) 的时候, \(d[i][j]=max(d[i-1][j],d[i][j-1])\) 。 \(LCS\) (最长公共子串) 我们设 \(d[i][j]\) 表示匹配到第一个串的第 \(i\) 位和第二个串的第 \(j\) 位的公共子串的长度。(即此时的这个子串一定是 \(i\) 和 \(j\) 都包含在其中的) 当 \(a[i]==b[j]\) 的时候, \(d[i][j]=d[i-1][j-1]+1\) 。 当 \(a[i]!=b[j]\) 的时候, \(d[i][j]=0\) \(LPS\) (最长回文子序列) 其实就是 \(UVa11404\) 的问题 我们设 \(d[i][j]\) 表示从 \(i\) 到 \(j\) 的最长回文子序列的长度。 当 \(s[i]==s[j]\) 的时候, \(d[i][j]=d[i+1][j-1]+2\) 。 当 \(s[i]!=s[j]\) 的时候, \(d[i][j]

史上最全的CSP2019复习指南

我只是一个虾纸丫 提交于 2019-12-04 01:17:34
CSP2019复习指南 知识点(大纲)内容参考于本人博客: 近22年NOIP考点一览 算法 基本算法: 模拟、暴力枚举 、排序、贪心、递归、递推、 贪心、二分、位运算 这些算法不再在此加以赘述,如有考前还不太懂的同学请尽快补习! 进阶算法 分治和归并排序 : 浅谈分治算法 详解归并排序 (附:) 求逆序对的方式 二分 : 二分写法选讲 差分和树上差分 : 浅谈差分 详解树上差分 位运算 : 常用位运算技巧 搜索 搜索是一种算法,但是把它单独拉开做一个专辑来训练。如果对搜索的基本概念和深搜、广搜还不是很了解的同学,以及不会写爆搜的同学,请尽快补习!! 剪枝 : 几种常见的剪枝方式 动态规划(DP) 动态规划也是一种算法,但它在算法竞赛中的作用甚至要等于其他算法的总和,光是这一种算法的衍生和派生算法以及各种次分类就有很多的学问。所以单独拿出一个专栏来讲。对于基础动态规划即线性动态规划不了解的同学请尽快补习!!再次重申,动态规划 非常重要 !! 背包问题 : 简单背包讲解 期望DP : 期望DP思路 状压DP : 浅谈状压DP 数学 由于年龄参差不齐,一般来讲 \(NOIP\) 中不会涉及太多的数学知识。但是这并不绝对,不涉及文化课上太深的数学知识不代表不考数学。数学推导和基础数学知识不仅锻炼思维,而且对联赛也有很大帮助。 基本数学: 质数和约数 : 详解质数相关 详解约数相关

动态规划总结

[亡魂溺海] 提交于 2019-12-03 23:21:13
Ø 动态规划基本思想 : 将待求解的问题分解为若干个子问题(阶段),按顺序求解子问题,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。 由于动态规划解决的问题多数有重叠子问题这个特点,为减少重复计算,对每一个子问题只解一次,将其不同阶段的不同状态保存在一个表中。 Ø 与分治的区别: 适合于用动态规划法求解的问题,经分解后得到的子问题往往不是互相独立的,即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解。 Ø 与搜索的区别: 搜索是遍历每一个可能的分支,动态规划是记忆化搜索,重叠子问题只计算一次 Ø 与贪心的区别: 在动态规划算法中,每步所做的选择往往依赖于相关子问题的解。因而只有在解出相关子问题后,才能做出选择。而在贪心算法中,仅在当前状态下做出最好选择,即局部最优选择。 Ø 动态规划算法的难点 从实际问题中抽象出动态规划表dp,dp表一般是一个数组,这个数组可能是一维的也可能是二维的,也可能是其他的数据结构。 Ø 动态规划求解问题的3个性质: (1) 最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。 (2) 无后效性:即某阶段状态一旦确定

程序员必须掌握的算法有哪些?

ぐ巨炮叔叔 提交于 2019-12-03 23:11:39
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我, 数据结构与算法应该要学习到哪个程度呢? ,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是 零散 的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过不错的文章给大家。大家也可以留言区补充。 一、算法最最基础 1、时间复杂度 2、空间复杂度 一般最先接触的就是时间复杂度和空间复杂度的学习了,这两个概念以及如何计算,是必须学的,也是必须最先学的,主要有最大复杂度、平均复杂度等,直接通过博客搜索学习即可。 文章推荐: 算法分析神器—时间复杂度 二、基础数据结构 1、线性表 列表(必学) 链表(必学) 跳跃表(知道原理,应用,最后自己实现一遍) 并查集(建议结合刷题学习) 不用说,链表、列表必须,不过重点是链表。 三分钟基础数据结构:如何轻松手写链表? 以后有面试官问你「跳跃表」,你就把这篇文章扔给他 2、栈与队列 栈(必学) 队列(必学) 优先队列、堆(必学) 多级反馈队列(原理与应用) 特别是优先队列,再刷题的时候,还是经常用到的,队列与栈,是最基本的数据结构,必学。可以通过博客来学习。相关文章: 三分钟基础知识:什么是栈?