动态规划

动态规划解决机器人网格路径问题!

断了今生、忘了曾经 提交于 2019-11-30 11:06:21
想获得更好的排版,请移步个人博客: https://pushy.site 无障碍物 题目(原题见 LeetCode - 62. 不同路径 ):一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。机器人 每次只能向下或者向右移动一步 。机器人试图达到网格的右下角(在下图中标记为“Finish”)。问总共有多少条不同的路径? 示例 1: 输入: m = 3, n = 2 输出: 3 解释: 从左上角开始,总共有 3 条路径可以到达右下角。 1. 向右 -> 向右 -> 向下 2. 向右 -> 向下 -> 向右 3. 向下 -> 向右 -> 向右 通过观察我们我们得出以下两个特点: 机器人所在的 正东方向和正南方向,只能有一条路径可以走,即直走 。 到某个点的路径 = 到该点 上一个单位的点 路径 + 到该点 左一个单位的点 路径。 为了验证第二个特点,我们假设网格是 2 * 2。如下图所示, 从 A 到达 D 点的路径总和就等于 A 点到达 B 点的路径 + 到达 C 点的路径总和 。 这样,我们不难写出递归代码: public int solution(int m, int n) { if (m <= 0 || n <= 0) return 0; else if (m == 1 || n == 1) return 1; int result = 0

详解动态规划——邹博讲动态规划

孤街醉人 提交于 2019-11-30 09:39:23
  动态规划,以空间换时间,自底向上求解   计算两字符串的最长公共子序列(可以不连续) /** 找出 两个 字符串 的公共 子序列(动态规划) @param str1 字符串1 @param str2 字符串2 */ void maxPublicSubSequence(char *str1, char *str2) { assert(str1 != NULL && str2 != NULL); // 字符串 1 长度 int str1Length = strlen(str1); // 字符串 2 长度 int str2Length = strlen(str2); // 开辟 二维 存储 数组 (并初始化 值为:0) int **postionArray = (int **)malloc(sizeof(int *) * (str1Length + 1)); for (int i = 0; i <= str1Length; i ++) { postionArray[i] = (int *)malloc(sizeof(int) * (str2Length + 1)); } for (int i = 0; i <= str1Length; i++) { for (int j = 0; j <= str2Length; j++) { postionArray[i][j] = 0; } }

剪绳子问题(动态规划,贪婪,递归)

。_饼干妹妹 提交于 2019-11-30 08:35:01
给你一根长度为n的绳子,请把绳子剪成m段(m、n都是整数,n>1并且m>1), 每段绳子的长度记为k[0],k[1],...,k[m]。请问k[0]xk[1]x...xk[m]可能的最大乘积是多少? 例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。 思路 注意 当长度大于3 f[n]才能得到绳子的最大乘积 动态规划 特征 从上往下分析问题,从下往上求解问题; 求一个问题的最优解;(最大值或者最小值) 问题能够分解成若干个子问题,并且子问题之间还有重叠的更小的子问题 分解后的小问题也存在最优解,如果把小问题的最优解组合起来能够得到整个问题的最优解,就可以使用动态规划 实现 public int cutRope(int target) { //排除特殊情况 if (target < 2) { return 0; } if (target == 2) { return 1; } if (target == 3) { return 2; } int[] products = new int[target + 1]; products[0] = 0; products[1] = 1; products[2] = 2; products[3] = 3; for (int i = 4; i <= target; i++) { int max = 0;

Max Sum (动态规划)

非 Y 不嫁゛ 提交于 2019-11-30 06:24:29
Given a sequence a[1]a[2]a[3]......a[n] your job is to calculate the max sum of a sub-sequence. For example given (6-154-7) the max sum in this sequence is 6 + (-1) + 5 + 4 = 14. Input The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow each line starts with a number N(1<=N<=100000) then N integers followed(all the integers are between -1000 and 1000). Output For each test case you should output two lines. The first line is "Case #:" # means the number of the test case. The second line contains three integers the Max Sum in the

动态规划:最长公共子序列和最长公共子串

孤街醉人 提交于 2019-11-30 06:13:56
一、最长公共子序列问题(LCS问题) 我们首先需要搞清楚以下两个概念:最长公共子序列 VS 最长公共子串: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。而最长公共子序列则并不要求连续。 问题描述: 给定两个字符串,求解这两个字符串的 最长公共子序列 (Longest Common Sequence)。比如字符串1:BDCABA;字符串2:ABCBDAB,则这两个字符串的最长公共子序列长度为4,最长公共子序列是:BCBA 动态规划解法分析: 设 A=(A1,A2,…An) 和 B={B1,B2,…Bm} 是两个序列,将 A 和 B的最长公共子序列记为 LCS(A,B) 找出LCS(A,B)就是一个最优化问题。因为,我们需要找到A 和 B中最长的那个公共子序列。而要找A 和 B的LCS,首先考虑A的最后一个元素和B的最后一个元素。 如果 An=Bm ,即X的最后一个元素与Y的最后一个元素相同,这说明该元素一定位于公共子序列中。因此,现在只需要找: LCS(An-1,Bm-1) 如果An != Bm ,产生了两个子问题:LCS(An-1,Bm) 和 LCS(An,Bm-1),因为序列A 和 序列B 的最后一个元素不相等,那说明最后一个元素不可能是最长公共子序列中的元素。求解上面两个子问题,得到的公共子序列谁最长,那谁就是 LCS(A,B)。用数学表示就是: LCS

面试问题之数据结构与算法:动态规划基本思想

≯℡__Kan透↙ 提交于 2019-11-30 04:32:37
转载于:https://blog.csdn.net/u013250416/article/details/80558542 一、基本思想   一般来说,只要问题可以划分为规模更小的子问题,并且原问题的最优解中包含了子问题的最优解,则可以考虑用动态规划解决。动态规划的实质是分治思想和解决冗余。因此,动态规划是一种将问题实例分解为更小的/相似的子问题,并存储子问题的解,使得每个子问题只求解一次,最终获得原问题的答案,以解决最优化问题的算法策略。 与贪心法的关系: 1.与贪心法类似,都是将问题实例归纳为更小的、相似的子问题,并通过求解子问题产生一个全局最优解。 2.贪心法选择当前最优解,而动态规划通过求解局部子问题的最优解来达到全局最优解。 来源: https://www.cnblogs.com/yichengming/p/11560276.html

动态规划

痞子三分冷 提交于 2019-11-30 03:50:43
1. 矩阵连乘问题 动态规划为先将子问题的最优解求出来,然后保存在二维数组中,然后再从下向上求解。 for(int len = 1; len <= n; len++) 从1到n设定子值问题的长度,当子问题为不同长度时,求解子问题的最优解,当遍历到n时,为最终问题的最优解。 for(int i = 1, j = i+len; j <= n; i++,j++) i为子问题的起始点,j为子问题的终止点,将子问题遍历整个最终问题。 int min = INF; for(k = i; k < j; k++) 找出子问题的分割点。 { int count = m[i][k] + m[k+1][j]+p[i-1]*p[k]*p[j]; 分割找到count if(count < min){ min = count;如果这个count比min小,赋值给min,为了求出最小的连乘次数 } } m[i][j] = min; 得到了m[i][j]的最小值。保存 } } return m[1][n] 找到了1-n连乘的最小值,返回 来源: https://blog.csdn.net/qq_32828145/article/details/101054201

82 算法:动态规划问题

流过昼夜 提交于 2019-11-30 03:23:33
0 引言 有一类问题,涉及到方案设计,由于方法有很多种,需要找到最佳方案。通常会把整个问题分解为许多小问题,解决这些小问题存在顺序,需要记住先解决的小问题的结果,作为后续问题的基础。通常会想到迭代和递归方法来解这一类的问题,很有实际意义。 1 相关教程 https://blog.csdn.net/u013309870/article/details/75193592 来源: https://www.cnblogs.com/ghjnwk/p/11550933.html

最小路径(动态规划)

半世苍凉 提交于 2019-11-30 03:17:57
1.最小路径和 给定一个只含非负整数的m*n网格,找到一条从左上角到右下角的可以使数字和最小的路径。 注:你在同一时间只能向下或者向右移动一步 样例1: 1 3 1 1 5 1 4 2 1 输出:7 样例2: 1 3 5 9 8 1 3 4 5 0 6 1 8 8 4 0 输出:12 来源: https://www.cnblogs.com/smilexuezi/p/11550129.html

【动态规划】旅行

*爱你&永不变心* 提交于 2019-11-30 02:02:15
原题传送门 思路 果断dp!!! dp[i]表示第i远的旅店到终点的路程数. 那么,若j(j<i)可以到达i,就将dp[j]加上dp[i]. 过于简单,不过多解释. 时间复杂度:O(n 2 ). 空间复杂度:O(n). Code #include<iostream> #include<algorithm> using namespace std; int a[50]={0,990,1010,1970,2030,2940,3060,3930,4060,4970,5030,5990,6010,7000}; int dp[50]; int A,B,n; int main() { cin>>A>>B>>n; for(int i=1;i<=n;i++) { cin>>a[13+i]; } n+=13; sort(a+1,a+n+1); dp[n]=1; for(int i=n;i>=0;i--) { for(int j=i+1;j<=n;j++) { if (a[j]-a[i]>=A&&a[j]-a[i]<=B) dp[i]+=dp[j]; } } cout<<dp[0]<<endl; return 0; } 来源: https://www.cnblogs.com/gongdakai/p/11031556.html