动态规划VS分治策略】的更多相关文章

•在用分治法解决问题时,由于子问题的数目往往是问题规模的指数函数,因此对时间的消耗太大. •动态规划的思想在于,如果各个子问题不是独立的,不同的子问题的个数只是多项式量级,而我们能够保存已经解决的子问题的答案,在需要的时候再找出已求得的答案,这样就可以避免大量的重复计算. 由此而来的基本思路是,用一个表记录所有已解决的子问题的答案,不管该问题以后是否被用到,只要它被计算过,就将其结果填入表中 斐波纳斯//哈哈 int F(int n, int a[N]) { ) ; ) ; a1=a[n-];…
原题 Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. Example: Input: [-2,1,-3,4,-1,2,1,-5,4], Output: 6 Explanation: [4,-1,2,1] has the largest sum = 6. Follow up:…
分治策略有一种“大事化小,小事化了”的境界,它的思想是将原问题分解成两个子问题,两个子问题的性质和原问题相同,因此这两个子问题可以再用分治策略求解,最终将两个子问题的解合并成原问题的解.有时,我们会有这样的疑惑:分治策略是将原问题分解成子问题,子问题又用分治策略求解,那分治策略到底是什么?这种感觉就像听到有人说“因为我说我没有做错事,所以我没有做错事”一样,让我们不知道他“没有做错事”的真正原因是什么. 对于上面的困惑,我本科的老师告诫过我们:“对于分治策略,当你们想不明白的时候只需记住两点:一…
在前面的博文(http://blog.csdn.net/jasonding1354/article/details/37736555)中介绍了作为分治策略的经典实例,即归并排序.并给出了递归形式和循环形式的c代码实例.可是归并排序有两个特点.一是在归并(即分治策略中的合并步骤)上花费的功夫较多,二是排序过程中须要使用额外的存储空间(异地排序算法<out of place sort>). 为了节省存储空间.出现了高速排序算法(原地排序in-place sort). 高速排序是由东尼·霍尔所发展的…
递归与分治策略之循环赛日程表 一.问题描述 设有n=2^k个运动员要进行网球循环赛.现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次: (2)每个选手一天只能参赛一次: (3)循环赛在n-1天内结束. 按此要求将比赛日程表设计成有n行和n-1列的一个表. 在表中的第i行,第j列处填入第i个选手在第j天所遇到的选手. 其中1≤i≤n,1≤j≤n-1.8个选手的比赛日程表如下图: 二.解决思想 按分治策略,我们可以将所有的选手分为两半,则n个选手的比赛日程表可以通…
递归与分治策略之棋盘覆盖 一.问题描述 二.过程详解 1.棋盘如下图,其中有一特殊方格:16*16 . 2.第一个分割结果:8*8 3.第二次分割结果:4*4 4.第三次分割结果:2*2 5.第四次分割结果:1*1 6.第一次分割后子棋盘的覆盖效果 三.代码实现 package cn.com.zfc.everyday.test; import java.util.Scanner; /** * * @title ChessboardCoverage * @describe 棋盘覆盖: * 利用分治…
[LOJ#575][LNR#2]不等关系(容斥,动态规划,分治FFT) 题面 LOJ 题解 一个暴力\(dp\),设\(f[i][j]\)表示考虑完了前\(i\)个位置,其中最后一个数在前面所有数中排名是第\(j\)大,那么转移的时候枚举一下当前数是第几大,并且满足不等式的限制就可以了,然后拿前缀和优化一下就可以做到\(O(n^2)\). 我们把所有连续的<看成一段,这样子题目就变成了每次要选出一段连续的上升序列,然后相邻两个连续段之间必须满足前一段的末尾要大于后一段的开头. 显然这个大于号是不…
问题描述: 给定已排好序的n个元素组成的数组,现要利用二分搜索算法判断特定元素x是否在该有序数组中. 细节须知: (1)由于可能需要对分治策略实现二分搜索的算法效率进行评估,故使用大量的随机数对算法进行实验(生成随机数的方法见前篇随笔). (2)由于二分搜索需要数据为有序的,故在进行搜索前利用函数库中sort函数对输入的数据进行排序. (3)代码主要用到的是经典的二分查找加上递归. (4)其中limit为所要从随机数文件中提取的数据的数量,以此为限来决定算法需要在多少个数据中进行搜索. (5)为…
Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个实数.每天随着市场的起伏波动, 两种金券都有自己当时的价值,即每一单位金券当天可以兑换的人民币数目.我们记录第 K 天中 A券 和 B券 的 价值分别为 AK 和 BK(元/单位金券).为了方便顾客,金券交易所提供了一种非常方便的交易方式:比例交易法 .比例交易法分为两个方面:(a)卖出金券:顾客提…
Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , 之后,即可自动化生产三边边长为 (a mod P,a^2 mod p,a^3 mod P) (a^4 mod p,a^5 mod p,a^6 mod P) .... (a^(3n-2) mod p,a^(3n-1) mod p,a^(3n) mod p) 的n个纸箱.在运输这些纸箱时,为了节约空间,必须将它们嵌套堆叠起来.一个纸箱可以嵌套堆叠进另一个纸箱当且仅当它的最短边.次短边和最长边 长度分别…
显然可以dp:设f[i]为前i个人最多能分多少组,则f[i]=max{f[j]}+1 (cmax<=i-j<=dmin). 容易发现d的限制是一段连续区间,二分或者随便怎么搞都行.c则有点麻烦,考虑分治.找到区间中c最大的位置,处理左边区间再向右边(包括该位置)转移,最后处理右边区间(当然就是cdq分治). 考虑怎么转移.设当前区间为[l,r],分段点为k,处理的左边位置为i,右边位置j的限制区间为[aj,j-1],aj单调不降.若i能更新j,则满足i+ck<=j且i>=aj.显然…
#include"iostream.h" void Merge(int c[],int d[],int l,int m,int r){ ,k=l; while((i<=m)&&(j<=r)){//循环两组中较小者先放入d[]暂存 if(c[i]<=c[j]) d[k++]=c[i++]; else d[k++]=c[j++]; } if(i>m) for(int q=j;q<=r;q++) d[k++]=c[q]; else for(int…
package chap04_Divide_And_Conquer; import static org.junit.Assert.*; import java.util.Arrays; import org.junit.Test; /** * 矩阵相乘的算法 * * @author xiaojintao * */ public class MatrixOperation { /** * 普通的矩阵相乘算法,c=a*b.其中,a.b都是n*n的方阵 * * @param a * @param b…
#include<stdio.h> #define LEN 8 int a[LEN] = { 5, 2, 4, 7, 1, 3, 2, 6 }; int Partition(int a[],int p,int r); void Swap(int *a,int *b); void QuickSort(int a[],int p,int r) { if(p<r) { int q=Partition(a,p,r);//q是当前划分点 printf("当前Q的值是:%d\n"…
/* fi表示第i行的最左最小元素的列小标,则有f0<f1<f2<...<fn-1 取数组的偶数行,组成新的子数组,递归求解最左最小元素的列下表,利用偶数项限定奇数项的范围,再求奇数项 */ #include<iostream> #include<vector> using namespace std; void findOddMin(vector<vector<int>> &a, int m, int n, vector&l…
#include"iostream.h" int BinarySearch(int a[],int left,int right,const int& x) { if(left<right) { ; if(x==a[middle]) return middle; ,right,x); ,x); } } void main(){ ]; cout<<"input the length of a[]"<<endl; cin>&g…
#include <ctime> #include <iostream> using namespace std; template <class Type> void Swap(Type &x,Type &y); inline int Random(int x, int y); template <class Type> void BubbleSort(Type a[],int p,int r); template <class Ty…
问题描述: 给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素,即如果将这n个元素依其线性序排列时,排在第k个的元素即为要找到元素. 细节须知:(与之前的随笔相比) (1)设置了对于程序运行次数的手动输入设定 (2)取消了文件的读入,直接生成随机数进行排序查找 (3)扩大了随机数的范围.数组的可申请大小 (4)时间统计精确到了微秒级 (5)运行结束后一次性写入提升了程序稳定性,写入的数据可用于数据分析图表 算法原理: 将n个输入元素划分成⌈n/5⌉个组,每组5个元素…
问题描述: 给定一个未知顺序的n个元素组成的数组,现要利用快速排序算法对这n个元素进行非递减排序. 细节须知: (1)代码实现了利用递归对数组进行快速排序,其中limit为从已有的随机数文件中输入的所要进行排序的数据的数量(生成随机数并写入文件的过程已在前篇中写出). (2)算法主要利用哨兵元素对数据进行分块,递归无限细分之后实现排序. (3)代码同样利用clock函数对算法的执行时间进行计算以进行算法的效率评估. (4)为了验证排序结果,代码实现了将排序后的内容输出到同文件夹下的sort_nu…
由于偷懒不想用泛型,所以直接用了整型来写了一份 ①首先你得有一个矩阵的class Matrix ②Matrix为了方便用下标进行运算, Matrix的结构如图:(我知道我的字丑...) Matrix.h代码如下:(个人并不喜欢把代码全写在一块,对于阅读者是相当巨大的负担,其实自己受不了(逃)) #pragma once #include<vector> using namespace std; class Matrix { public: vector<vector<int>…
Dynamic Programming   Dynamic Programming是五大常用算法策略之一,简称DP,译作中文是"动态规划",可就是这个听起来高大上的翻译坑苦了无数人,因为看完这个算法你可能会觉得和动态规划根本没太大关系,它对"动态"和"规划"都没有太深的体现.   举个最简单的例子去先浅显的理解它,有个大概的雏形,找一个数组中的最大元素,如果只有一个元素,那就是它,再往数组里面加元素,递推关系就是,当你知道当前最大的元素,只需要拿…
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? Note: Given n will be a positive integer. 题目分析:每次只能走1或2步,问n步的话有多少中走法???? 可以用动态规划和递归解…
策略是面向问题的,算法是面向实现的. 一.不同算法策略特点小结 1.贪心策略 贪心策略一方面是求解过程比较简单的算法,另一方面它又是对能适用问题的条件要求最严格(即适用范围很小)的算法. 贪心策略解决问题是按一定顺序,在只考虑当前局部信息的情况下,就做出一定的决策,最终得出问题的解. 即:通过局部最优决策能得到全局最优决策 2.递推策略 递推也是由当前问题的逐步解决从而得到整个问题的解,依赖于信息间本身的递推关系,每一步不需要决策参与到算法中,更多用于计算 3.递归策略 递归常常用于分治算法.动…
分治策略:解决问题的典型策略,分而治之 将问题分为若干更小规模的部分 通过解决每一个小规模部分问题,并将结果汇总得到原问题的解 递归算法与分治策略 递归三定律 体现了分支策略 应用相当广泛 排序 查找 遍历 求值等 优化问题 计算机科学中许多算法都是为了找到某些问题的最优解 两点之间最短路径 能最好匹配一系列点的直线 满足一定条件的最小集合 经典案例:找零兑换 贪心策略 兑换最少个数的硬币 贪心策略及失效 63=252+101+1*3 63=21*3 递归解法 步骤 确定基本结束条件 需要兑换的…
今天晚自习机房刷题,有一道题最终WA掉两组,极其不爽,晚上回家补完作业欣然搞定它,特意来写篇博文来记录下 (最想吐槽的是这个叫做分治的分类,里面的题目真的需要分治吗...) 先来说下分治法 分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之. 分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并…
由于种种原因(看这一章间隔的时间太长,弄不清动态规划.分治.递归是什么关系),导致这章内容看了三遍才基本看懂动态规划是什么.动态规划适合解决可分阶段的组合优化问题,但它又不同于贪心算法,动态规划所解决的问题的各个阶段是相互关联的,一个阶段的选择会影响其它阶段的选择.动态规划有两个优点:一是可以排除一些解,另一个是可以帮助我们系统化的解决问题,使问题变得清晰. 下面就说一下我对动态规划.分治.递归这三者的理解.分治算法是将原问题分解成两个较小的问题,而动态规划是将问题分成不同的阶段(步骤),当然,…
大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang 以下实现最大子数组的分治策略,算法来自<算法导论> #include<iostream> using namespace std;  struct ans {     int low;     int high;     int sum; };   ans MAXIMUM_CROSSING_SBUARRAY(int * A, int low, int mid, int high)…
剑指Offer--分治算法 基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)-- 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关.问题的规模越小,越容易直接求解,解题所需的计算时间也越少.例如,对于n个元…
Decription: 某天WJMZBMR学习了一个神奇的算法:树的点分治! 这个算法的核心是这样的: 消耗时间=0 Solve(树 a) 消耗时间 += a 的 大小 如果 a 中 只有 1 个点,退出;否则在a中选一个点x,在a中删除点x,那么a变成了几个小一点的树,对每个小树递归调用Solve. 我们注意到的这个算法的时间复杂度跟选择的点x是密切相关的. 如果x是树的重心,那么时间复杂度就是O(nlogn) 但是由于WJMZBMR比较傻逼,他决定随机在a中选择一个点作为x! Sevenkp…
Git速成学习笔记整理于廖雪峰老师的官网网站:https://www.liaoxuefeng.com/ 通常合并分支时,如果可能用Fast forward模式,但是在这种模式下,删除分支后,会丢掉分支信息. 如果强制禁止Fast forward模式,Git就会在merge时生成一个新的commit,这样从分支历史上就可以看出分支信息. 下面我们仍实战一下 --no-ff方式的git merge: 首先,我们仍创建并切换分支: $ git checkout -b dev Switched to a…