动态规划

第九届蓝桥杯B组第四题--测试次数(C语言)

半城伤御伤魂 提交于 2020-02-11 20:59:11
第九届蓝桥杯B组第四题–测试次数(C语言) 一.比赛题目 1.题目要求 x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。 各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n;为了减少测试次数,从每个厂家抽样3部手机参加测试。 某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢? 2.输入与输出 输出: 填写最多测试次数; 二.分析过程 答案为:19 1.方法分析 我想很多人最开始和我一样都会想用二分法来做这个题,但是二分的话,500层一摔手机碎了,250碎了,125碎了;然后三个手机碎完,我们都不知道手机耐摔指数; 而这道题和区间动态规划特别像,所以就用动态规划的方法来做。 2.做题思路 假如动态规划的话,我们首先确定状态变量: i 楼层数 j 手机数 k 机会数 假如我们有k次机会来砸的话: 碎了 碎了 k层楼来砸

动态规划( python)

吃可爱长大的小学妹 提交于 2020-02-11 03:55:59
  动态规划的三要素:最优子结构,边界和状态转移函数,最优子结构是指每个阶段的最优状态可以从之前某个阶段的某个或某些状态直接得到(子问题的最优解能够决定这个问题的最优解),边界指的是问题最小子集的解(初始范围),状态转移函数是指从一个阶段向另一个阶段过度的具体形式,描述的是两个相邻子问题之间的关系(递推式)   重叠子问题,对每个子问题只计算一次,然后将其计算的结果保存到一个表格中,每一次需要上一个子问题解时,进行调用,只要o(1)时间复杂度,准确的说,动态规划是利用空间去换取时间的算法.   判断是否可以利用动态规划求解,第一个是判断是否存在重叠子问题, 例子: 爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数。 示例 1: 输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。 1. 1 阶 + 1 阶 2. 2 阶 示例 2: 输入: 3 输出: 3 解释: 有三种方法可以爬到楼顶。 1. 1 阶 + 1 阶 + 1 阶 2. 1 阶 + 2 阶 3. 2 阶 + 1 阶https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/23/dynamic-programming

动态规划例题

安稳与你 提交于 2020-02-11 02:15:59
这里记录一些动态规划的例题,不断积累,不断补充。 1、不等式数列 题目描述: 对1到n这n个整数进行全排列,在每一个排列中每两个相邻的整数之间插入>或<,使得不等式成立。现要求<的个数为k,即>的个数为n-k-1,求问满足要求的排列个数。例如,现在给定n=3,k=1,则满足要求的排列有1<3>2,2>1<3,2<3>1,3>1<2这四种情况,即结果为4。参数范围K < n <= 1000。 解题思路: 暴力搜索复杂度为n!,肯定是不行的。虽然可以进行一定程度的剪枝,比如在遍历每一个位置的数字时,判断当前<是否已经用完,但这只是杯水车薪。遇到这种问题,第一反应肯定是需要使用动态规划,当然难点就在于如何构造递推公式。针对本题目,我们设定dp[i][j]为在n=i,k=j的情况下的排列数,则递推公式为 dp[i][j] = dp[i - 1][j - 1] * (i - j) + dp[i - 1][j] * (j + 1) 怎么理解这个公式呢?其实就要考虑如何从i-1过渡到i。当n从i-1增加到i,新增的数字i要比之前的1到i-1都大,所以无论把i插入到哪个位置,它都会比左右两个数字a和b都大。假如a<b,将i插入到两数之间,不等式变为a<i>b,小于号<数量不变;如果a>b,不等式变为a<i>b,小于号<数量加1。所以为了求解dp[i][j],就要考虑dp[i-1][j]和dp[i

floyd+动态规划 hdu-4571-Travel in time

╄→尐↘猪︶ㄣ 提交于 2020-02-10 11:10:49
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4571 题目大意: 有n个景点,每个点都有个游玩时间ci,游玩后得到的满意度si。给一个起点s和终点e,两个景点间有条无向边,权值为时间。从起点出发,在给定时间限制下,到达终点,问能获得的最大的满意值,只有游玩了景点才能获得该景点的满意值,并且上个游玩景点的满意度必须大于后一个游玩的景点满意度。 解题思路: 图上的dp. 见到图论就晕啊啊啊。先求出不游玩时,任意两点的到达时间,用floyd求。 dp[i][j]表示到达第i个点,用时为j时,能到达的最大的满意度。 本题的关键是先对每个景点的满意度从小到大排序,然后对于第i个景点枚举时间j(从大到小,因为一个景点只能游一次), 在枚举前面的i-1个景点,通过前面的满意度得出当前的满意度。转移方程还是很好写的。 代码: #include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include

无向图上的动态规划

ぐ巨炮叔叔 提交于 2020-02-10 01:20:30
牛客的题 有一种情况,就是k小于n时候,1到不了k,那就把dp全设置成负无穷(-1不行)这样就用不到了 #include<iostream> #include<cstring> #include<queue> #include<algorithm> #include<cstdio> using namespace std; typedef long long ll; const int maxn = 1e5 + 7; const ll INF = 1e17 + 7; ll dp[maxn]; ll map[220][220]; struct Node { int t, p, val; }que[maxn]; bool bml(Node a, Node b) { return a.t < b.t; } int main() { int n, m, q; scanf("%d%d", &n, &m); for (int i = 0; i <= n; i++) { for (int j = 0; j <= n; j++) { if (i == j) map[i][j] = 0; else map[i][j] = INF; } } int x, y; for (int i = 0; i < m; i++) { scanf("%d %d", &x, &y); map[x][y] = map[y

leetcode 动态规划入门问题细化解析(一)

烈酒焚心 提交于 2020-02-09 18:52:17
1.最小花费爬楼梯 https://leetcode-cn.com/problems/min-cost-climbing-stairs/ 大佬的题解,跟官方解答思路一样(自己加了注释内容) class Solution { public : int minCostClimbingStairs ( vector < int > & cost ) { int c1 = cost [ 0 ] ; int c2 = cost [ 1 ] ; int N = cost . size ( ) ; for ( int i = 2 ; i < N ; ++ i ) { int c3 = min ( c1 , c2 ) + cost [ i ] ; //从i = 2开始,本层的体力加上min(到达第i - 2层花费体力的最小值,到达第i - 1层花费体力的最小值) c1 = c2 ; //c1为到达第i - 1层花费体力的最小值 c2 = c3 ; //c2为到达第i层花费体力的最小值 } return min ( c1 , c2 ) ; //比较到N - 1和N - 2花费体力的值 } } ; 作者:da-li-wang 链接:https://leetcode-cn.com/problems/min-cost-climbing-stairs/solution/c-dong-tai-gui-hua

强大的动态规划

浪子不回头ぞ 提交于 2020-02-09 16:53:50
  动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治算法不同的是,适合于用动态规划法求解的问题,经分解得到的子问题往往不是相互独立的。若用分治算法来解决这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要耗费指数时间。然而,不同子问题的数目尝尝只有多项式量级。在用分治算法求解时,有些子问题被重复计算了多次。如果我们能保存已解决的子问题的答案,而在需要的时再找出已求得的答案,这样就可以避免大量的重复计算,从而得到多项式时间算法【动规方程】。为达到此目的,可以用一个表来记录所有已解决的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中,这就是动态规划法的基本思想。具体的动态规划法多种多样,但它们具有相同的填表格式。   动态规划算法适用于解最优化问题。通常科安一下4个步骤设计:   (1)找出最优解的性质,并刻画其结构特征【找出动规方程】;   (2)递归地定义最优值;   (3)以自底向上的方式计算出最优值;   (4)根据计算最优值时得到的信息,构造最优解;   步骤(1)~(3)是动态规划算法的基本步骤。在只需要求出最优值的情形,步骤(4)可以省去。若需要求出问题的最优解,则必须执行步骤(4)。此时,在步骤(3)中计算最优值时,通常需记录更多的信息,以便在步骤(4

动态规划专题--------计蒜客--T1208--放苹果

喜欢而已 提交于 2020-02-08 22:19:52
题目链接: https://nanti.jisuanke.com/t/T1208 题目描述 小蒜想知道把 M 个同样的苹果放在 N 个同样的盘子里,允许有的盘子空着不放,共有多少种不同的分法?(用 K 表示)5,1,1 和 1,5,1 是同一种分法。 输入格式 第一行是测试数据的数目 t ( 0 ≤ t ≤ 20 ) 。 以下每行均包含两个整数 M 和 N,以空格分开。1 ≤ M , N ≤ 10。 输出格式 对输入的每组数据 M 和 N,用一行输出相应的 K。 输出时每行末尾的多余空格,不影响答案正确性 样例输入 1 7 3 样例输出 8 这题可以用递归的方法写,也可以用动态规划的思路写。 递归方法: 递归超详解 (个人认为递归的方法比动态规划好理解一些) 动态规划思路: (i,j)代表i个苹果放j个盘子里 要解动态规划的题,最关键的就是找到动态转移方程,要找到动态转移方程就是要找到递推式。这题可以对有无空盘子进行讨论: 1.有空盘子时,(i,j)=(i,j-1),就像5个苹果放3个盘子里,如果有空盘子,这个问题就等价于5个苹果放2个盘子里 2.无空盘子是,(i,j)=(i-1,j),这里因为每个盘子里都有苹果,所以问题每个盘子可以减去一个苹果,就像5个苹果放3个盘子里,因为没有空盘子,所以每个盘子里面至少有一个苹果,即两个苹果放盘子里。 代码: #include

动态规划

拈花ヽ惹草 提交于 2020-02-08 21:21:39
动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。 动态规划算法的基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段), 按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时, 列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。 依次解决各子问题,最后一个子问题就是初始问题的解。 https://blog.csdn.net/ailaojie/article/details/83014821 来源: https://www.cnblogs.com/h694879357/p/12285125.html

动态规划解题步骤

自闭症网瘾萝莉.ら 提交于 2020-02-08 19:26:12
动态规划 1. 题目特点 计数 -有多少种方式解决。 求最大最小值 -从左上角走到左下角路径的最大数字之和 求存在性 -博弈中,是否存在红方胜的解 2.解题步骤 以下都是以 lintcode 中第 669 题为例: “给出面额为2,5,7的硬币以及总金额为27. 写一个方法来计算给出的总金额可以换取的最少的硬币数量. 如果已有硬币的任意组合均无法与总金额面额相等, 那么返回 -1.” 1、确定状态 状态 :解动态规划的时候需要开一个数组,每个数组的每个元素 f[i] 或 f[i][j] 所代表的含义就是状态。类似于数学中的 x、y、z 。 确定状态需要做的两件事 : -最后一步 指 最优策略 中的最后一个步骤。 -子问题 指问题一样,规模更小的问题。 做完以上两个步骤之后,就可以设状态为:f[x] 或 f[x][y] = 子问题于原问题相同的部分。把原问题和子问题公共部分抄下来,观察变量,有几个就用几维数组。 2、转移方程 就把 “确定状态” 中的状态表达式,写出来并写出必要的解释。 (以下两步是在写程序的时候非常重要的) 3、初始条件和边界条件 方程:f[x] = min {f[x-2]+1, f[x-5]+1, f[x-7]+1} 两个问题:x-2, x-5, x-7 会不会小于零?什么时候停下? 解:(1)边界条件:如果没有结果就定义 f[y] = 正无穷。 (2)初始条件