动态规划

算法第三章作业

青春壹個敷衍的年華 提交于 2019-12-03 10:43:38
1. 对动态规划算法的理解 动态规划与分治法一样,需要将大问题化小,不同的是分治法往往子问题相互独立,而动态规划子问题有重复,做用分治法的思维去做会出现大量重复计算,增加复杂度。而动态规划重在建表记录已解决的子问题的答案,其步骤为 (1)找出最优解性质,并刻画其结构特征 (2)递归的定义最优值 (3)以自底向上的方式计算最优值 (4)根据计算最优值时得到的信息,构造最优解 2. 编程题1、2的递归方程 3-1 单调递增最长子序列 longest[i]默认值全为1,sequence[i]为序列,则 j从1到i-1 longest[i] = max(longest[i] , longest[j] + 1 ) for (int i = 1; i < n; i++) { for (int j = 0; j < i; j++) { if (sequence[i] > sequence[j]) { longest[i] = (longest[i] > longest[j] + 1) ? longest[i] : longest[j] + 1; } } } 3-2 租用游艇问题 rent[i][j]表示直接从i到j的费用初始值leastMoney[1] = 0, leastMoney[2] = rent[1][2]则j从1到i-1leastMoney[i] = max(leastMoney[j]

87. 扰乱字符串

随声附和 提交于 2019-12-03 10:25:32
题目描述: Given a string s1, we may represent it as a //分割 binary tree by partitioning it to two non-empty substrings recursively. Below is one possible representation of s1 ="great": great / \ gr eat / \ / \ g r e at / \ a t //爬行字符串 To scramble the string, we may choose any non-leaf node and swap its two children. For example, if we choose the node"gr"and swap its two children, it produces a scrambled string"rgeat". rgeat / \ rg eat / \ / \ r g e at / \ a t We say that"rgeat"is a scrambled string of"great". Similarly, if we continue to swap the children of nodes"eat"and"at", it produces a

动态规划训练之十九

醉酒当歌 提交于 2019-12-03 10:25:22
分析: 考虑初级的 dpO(N^3^) code: for(ri K=1;K<=n;K++) for(ri i=1;i<=n;i++){ for(ri j=i-1;j>=1;j--) if(sum[i]-sum[j]<=w) dp[i][K]=min(dp[j][K-1]+K*(sum[i]-sum[j])+querymax(j+1,i)-querymin(j+1,i),dp[i][K]); 考虑 能不能降维 发现这个K很多事 想到把K这一维删去 这里就要用到 费用提前算 的思想了 补充:费用提前算 https://www.luogu.org/problem/P2365 分析: 考虑 最原始的dp: f[i,j]=min{f[k,j-1]+(s×j+sumT[i])×(sumF[i]-sumF[k])}(0<=k<i) 复杂度 N^3^ 把费用提前算:将以后会算上的,先加上,除掉后效性 f[i]=min{f[k]+sumT[i]×(sumF[i]-sumF[k])+s*(sumF[n]-sumF[k])} 这题数据也就N^2^,其实这题还可以 斜率优化 ,当然懒得说了 回到正题 dp[i,K]=min(dp[j,K-1]+K*(sum[i]-sum[j])+querymax(j+1,i)-querymin(j+1,i),dp[i,K]) 经过变换: dp[i]=min{dp[j]+

算法第三章动态规划作业总结

人盡茶涼 提交于 2019-12-03 10:16:21
1. 对动态规划算法的理解 动态规划法用到了分治的思想,结合了备忘录,从最小问题开始累积记录,直到得到最顶上的问题的结果。 2. 分别列出编程题1、2的递归方程 第一题 a[i] = max(a[j]+1, a[i]) 第二题 if(b[i][k]+b[k][j]<dp[i][j]) b[i][j]=b[i][k]+b[k][j] 3. 说明结对编程情况 在课余我和小伙伴一起讨论了作业题目,各打了两题,交换了思想。 来源: https://www.cnblogs.com/szkkk2000/p/11788180.html

算法设计与分析-动态规划

与世无争的帅哥 提交于 2019-12-03 10:12:00
一、对动态规划算法的理解 动态规划算法与分治法很相似,相同之处是将原问题分解为若干个子问题,再根据子问题求得原问题的解。不同之处是动态规划的子问题之间不是相互独立的,经常是有重叠的。所以为了避免重复计算,可以制作一个表来记录已经解决的子问题,当再次遇到子问题时,查表即可得到答案。该算法通常用于求解具有最有性质的问题,并且其子问题也具有最优性质且重叠,即最优子结构性质和子问题重叠性质。 用动态规划算法解决该类问题的基本步骤是: 1、找出最优解的性质及结构 2、建立子问题最优值的递归关系(即写出递归方程)3、以自底向上的递归形式计算最优值(也可以是自顶向下,即备忘录法)4.根据问题需要求出最优解,最优解是使最优值成立的解,可在第三步中记录相关信息求得。 二、递归方程 1.由n个数组成的序列的最长单调递增子序列。 递归方程:len[ i ] = max ( len [ j ] + 1 ) ( 0 < j < i ) , len [ i ] 表示从第一个数到第 i 个数 组成的序列的最长单调递增子序列的长度 2.长江游艇俱乐部在长江上设置了n个游艇出租站1,2,…,n。游客可在这些游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i<j<=n。试设计一个算法,计算出从游艇出租站1 到游艇出租站n所需的最少租金。 递归方程

算法第三章作业

半世苍凉 提交于 2019-12-03 10:10:41
一:对动态规划的理解 动态规划具备一下三个特点: 把原来的问题分解成了几个相似的子问题。(强调“相似子问题”) 所有的子问题都只需要解决一次。(强调“只解决一次”) 储存子问题的解。(强调“储存”) 一个很简单的例子就是斐波那契数列,在画出树形结构的时候发现很多分支都存在重复计算 动态规划通过巧妙的分治和记录子问题的解,可以给原本时间开销巨大的问题提供时间效率上大大优化的解决方案。 动态规划的本质对问题状态的定义和状态转移方程的定义,而储存重叠子问题的解只是一种“技巧”,与动态规划的本质无关(这是关键!!) 二: 编程题1: 思路 用i指针遍历数组 然后用j从0遍历到i 找出小于i的数字,并在dp数组+1 if(a[i] > a[j] && store[i] < store[j] + 1) store[i] = store[j] + 1; 最后在dp数组里找最大值。 编程题2: 思路 从最底层开始逐渐计算,其中站之间可能相邻,也可能不相邻,需要进行递归检测。 如果 A B C 之间若 AB + BC < AC 则AC之间的最少费用不是相邻得到的,可以知道B肯定是一个站点。 int temp = c[i][k] + c[k][j]; if(temp < c[i][j]) c[i][j] = temp; 最后返回c【1】【n】 结对编程情况:目前在leetcode上寻找多道动态规划题目

第三章作业

大憨熊 提交于 2019-12-03 10:10:34
一、动态规划算法的理解    动态规划的算法从某方面来说是一个决策问题。举个例子,小明从起点a要到目的地d,中途可能会经过b1、b2、b3、c1、c2、c3,而经过这些地方的花费不同,小明要如何走才能使得花费最大?    从动态规划的角度讲,如果小明能知道从b到d的最短费用(cost[b][d])再加上cost([a][b])的最小费用,就可以知道他到达终点d的最优解了。而要知道cost[b][d],必须先知道min(cost[c][d])......这样层层递归,把一个大的问题分解为一个个小的问题,而这些小问题又互相依赖,有先后顺序,小问题的最优解又关系到大问题的最终解,这就是从决策方面来讲的一种动态规划。动态规划常常借助二维数组作为表格,来记录一个个小问题的递进,最终得到大问题的答案。 二、编程题1、2的递归方程 1.单调递增最长子序列 假设a[j]表示以第j个数结尾的最长单调递增子序列。 其递归方程为 a[i] = max(a[j] + 1, a[i]) (i >= 1, 0 <= j < i) 2.租用游艇问题 假设cost[i][j]表示从站点i到站点j的最小花费。 cost[i][j] = max(cost[i][j], cost[i][k]+cost[k][j]) (1 <= i < n, i < j <= n, i <= k <= j) 三、结对编程总结

动态规划

偶尔善良 提交于 2019-12-03 09:51:17
简介 动态规划遵循一套固定的流程:递归的暴力解法( O(2^n) ) -> 带备忘录的递归解法( O(n) ) -> 非递归的动态规划解法( O(n) )。 「自顶向下」: 是从上向下延伸, 都是从一个规模较大的原问题比如说 f(20),向下逐渐分解规模,直到 f(1) 和 f(2) 触底,然后逐层返回答案。 「自底向上」: 直接从最底下,最简单,问题规模最小的 f(1) 和 f(2) 开始往上推,直到推到我们想要的答案 f(20), 动态规划解法 1. 将原问题分解为子问题 f(0),f(1),f(2)...f(n) 2. 确定状态 f(n) 3. 确定一些初始状态(边界条件)的值 f(n)=0 4. 确定状态转移方程(当前子问题值与前一个子问题值的关系) f(n) 是一个状态 n,这个状态 n 是由状态 n - 1 和状态 n - 2 相加转移而来,这就是状态转移 动态规划问题最困难的就是写出状态转移方程。 适合使用动规求解的问题 1. 问题具有最优子结构(问题的最优解所包含的子问题的解也是最优的) 2. 求最优解问题 动态规划1:爬楼梯,求共多少爬法(n为正整数) /** * 方法1:递归(超时):太多冗余 */ class Solution1 { public static int climbStairs(int n) { if(n==1 || n==2)return n;

算法第三章作业

允我心安 提交于 2019-12-03 09:50:06
1. 你对动态规划算法的理解(2分) 答:动态规划算法通常用于求解具有某种最优性质的问题。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。 2. 分别列出编程题1、2的递归方程(2分) 答: (1)编程题1的递归方程为 m [ i ] = m a x { m [ k ] |,a [ k ] < a [ i ] } (1 < = k < i) (2)编程题2的递归方程为 m [ i ] = m i n { c [ i ] [ k ] + m [ k ] }(i < k <=n)或者m [ i ][ j ] = m i n { c [ i ] [ k ] + m [ k ][ j ] }(i < k <= j) 3. 说明结对编程情况(1分) 答:和队友一起讨论了结对编程作业,对于动态规划

第三章作业

一世执手 提交于 2019-12-03 09:46:53
一、对动态规划算法的理解   动态规划算法与分治法类似,其基本思想是将待求解的问题分解成若干子问题,先求解子问题,再结合这些子问题的解得到原问题的解。但是,适合用动态规划算法来求解的问题经分解得到的子问题往往不是相互独立的,而用分治法求解时则会对有些子问题进行重复的求解,以致耗费过多的时间,因此,动态规划引入了一个表格来记录已经求解了的子问题,避免重复求解。用动态规划法求解的主要步骤是分析最优解的性质,列出递归方程。 二、编程题的递归方程 1. 单调递增最长子序列   序列A = {a0,a1,...,ai,...an}, longest[i]表示序列A从a0到ai的单调递增子序列长度,初始值为1.   递归方程:longest[i] = max(longest[i], longest[j]+1) (i >= 1, 0 <= j < i) 1 int main() { 2 int n, max = 0, a[MAX], longest[MAX] = { 1 }; // 单调递增子序列长度至少为1;longest数组记录已解决的子问题的答案 3 cin >> n; 4 for (int i = 0; i < n; i++) 5 cin >> a[i]; 6 for (int i = 1; i < n; i++) { 7 for (int j = 0; j < i; j++) { 8