时间复杂度

对分治法思想的体会 & 结对编程情况汇报

喜夏-厌秋 提交于 2019-12-01 07:54:55
一、对分治思想的体会 1、帮助我们解决问题。 分治法,对大的问题拆封成规模较小的问题,我们求解小问题,再把小问题的答案合并起来,得出大问题的答案。大问题思考起来比较乱,犯迷糊,不易想到解决方法,比如汉诺塔问题。分解成小问题,我们就容易想出方法来解决问题 2、时间复杂度低 分治法思想核心是递归,递归的时间复杂度低。算法的复杂度低,提高了算法的质量 二、结对编程情况汇报 3道题都做完且答案正确,第三道题,没有按时间复杂度为O(logn)编程,后来查找资料知道如何写出O(logn)的算法。第一题,开始没有语法错误,但是答案不正确,因为没有用多几个不同特殊的例子去检验答案的正确性。 第二题是在第一道题基础上的修改,所以思路有了,想清楚两道题的不同点后,比较快速的做出来。 来源: https://www.cnblogs.com/666AAAA/p/11670987.html

模拟测试69

风流意气都作罢 提交于 2019-12-01 07:47:43
T1:   不难发现间隔为$n$的倍数的两列,放的棋子数必须相同。   可以用背包DP解决,设$dp[i][j]$为考虑到第$i$列,放了$j$个棋子的方案数。   DP范围不能超过$n$,但可以用上面的性质。   每一列的摆放都是独立的,所以可以用快速幂求出。   状态转移方程:     $dp[i][j]=\sum \limits_{k=0}^{min(j,n)} dp[i-1][j-k]*s[i][k]$     $s[i][j]=(C_n^j)^{\large \frac{n-1}{i}+1}$   时间复杂度$O(n^4)$。 T2:   对于所有点,合法左端点的位置一定在最左侧的大于它的数右面。   维护一个单调递减的单调栈,每个点对应的左端点可以由弹掉的元素转移而来。   但前提是弹掉元素对应的左端点的值小于当前左端点的值,不然不合法。   时间复杂度$O(n)$。 T3:   没有办法直接维护,只能莫队。   普通莫队需要用线段树维护最长值域连续段,会超时。   所以这题要用到回滚莫队。   对于在每个块中的询问,右端点严格单调,所以不需要回滚。   而左端点要回溯,需用栈记录状态。   更新答案可以用类似链表的思路,只记录连通区间两侧的答案即可。   时间复杂度$O(n\sqrt{n})$。 来源: https://www.cnblogs.com/hz

时间、空间复杂度推导

浪子不回头ぞ 提交于 2019-12-01 07:27:27
时间复杂度公式推导 首先假设每一行的代码执行时间是相同的 推导过程 案例 def zx(n): sum = 0 for i in range(n): sum += 1 print(sum) 那么这个函数执行花费的时间为2n+1*time def zx(n): sum = 0 for i in range(n): for i in range(n): sum +=1 print(sum) 这个函数的执行花费时间为$2n^2$+n+1*time 总结 $T_(n)$表示代码执行的时间,n表示数据的规模,$f_(n)$表示每行代码执行次数的总和,O表示执行花费总时间和执行代码总次数成正比 $T_(n)$=O($f_(n)$) 当n的数据规模很大的时候,案例中的个位数的代码执行次数可以忽略不计,同时低阶和系数的影响也是可以忽略的,最后得出两段代码的时间复杂度为 $T_(n)$=O(2n+1)=O(n) $T_(n)$=O(2$n^2$+n+1)=O($n^2$) 时间复杂度排序 常数阶O(1) a = 1 b = 2 c = a+b 一般情况下,只要代码的执行时间不随n的增大而增大,这样代码的时间复杂度我们就记作O(1) 对数阶O($log$n)和O(n$log$n) def zx(n): i = 1 while i <= n: i = i * 2 print(i) T(n)=O($log

算法分析第二章之分治

自古美人都是妖i 提交于 2019-12-01 07:23:13
什么是分治法: 分治法分为三步: 1.分解子问题 2.求解子问题 3.合并子问题(有时候第三步可以不做,因为有时候大问题的答案往往就是子问题的答案,无需合并) 分治法的时间复杂度计算: 令人开心的是,分治法因为其基本思想而有自己的时间复杂度计算公式,不必再为了分析时间复杂度看一行行的代码。 其公式为: 心得体会 :不用再为分治法的时间复杂度发愁了。直接计算就好。 结对编程情况汇报: 与队友结对最大的感受就是,每个人写的代码都可以看出自己的代码风格。比如我队友而言,喜欢用flag变量来对问题做一些处理,且有时候一些小细节不太注意往往就会出错,纠结好久。我以后写代码要好好地仔细审题。 来源: https://www.cnblogs.com/lycsuper/p/11668364.html

[洛谷]P3952 时间复杂度

女生的网名这么多〃 提交于 2019-12-01 07:16:16
[洛谷]P3952 时间复杂度 题目描述: 恶心的代码: #include <bits/stdc++.h> using namespace std; inline void read(int &x){ x=0;int f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } x*=f; } bool judge(string a,string b) { if(a.size()>b.size()) return 1; if(a.size()==b.size() && a>b) return 1; return 0; } int findO(string s) { for(int i=0;i<s.length();i++) if(s[i]=='(') { if(s[i+1]=='n') if(isdigit(s[i+4])) return (s[i+4]-'0')+10*(s[i+3]-'0'); else return s[i+3]-'0'; if(isdigit(s[i+1])) return 0; } } string work(int line

算法第二章作业

自古美人都是妖i 提交于 2019-12-01 07:12:16
1.请谈一下你对分治法思想的体会 起初对分治法的初步理解就是把问题分成几个子问题,感觉没多大作用。但是在时间复杂度的对比上,我才发现分治法十分的奇妙,再配合用上递归的方法,可以大大减少其时间复杂度。在编程的时候,我也照着书本上去使用分治法,体会到了这种方法的特别之处。 2. 结对编程情况汇报 结对编程过程中,我们都会去打自己的代码,然后再对比各自的代码,相互借鉴,并且选择一个更简便的代码去执行。 来源: https://www.cnblogs.com/lisihao/p/11666931.html

数据结构,算法宏观印象构建

余生颓废 提交于 2019-12-01 07:08:57
数据结构,算法宏观印象构建 摘要 什么是数据结构? 为什么需要不同种类的数据结构? 数据结构的分类 什么是算法 为什么需要算法 算法性能的衡量标准 什么是数据结构? 逻辑结构:描述数据之间的关系 物理结构:描述数据存储的方式 为什么需要不同种类的数据结构? 为了更加高效的处理数据,主要体现在存储和检索方面。 如同不同的数据类型一样,通过阶梯式的定义,既有满足小数值运行的byte类型,也有支持大数值运算的long类型。这样不仅满足运算的最大支持(long),同时也能节省系统内存资源(byte)。 换句话说,数据结构和数据类型的设计目的殊途同归,都是系统资源分配优化的方案。 数据结构的分类 逻辑结构 1,集合结构 例如一个集合中包含橘子,苹果和香蕉。 集合具有三大特性: 唯一性 互斥性 无序性 2,线性结构 元素存在一对一的相互关系 3,树形结构 元素存在一对多的相互关系 4,图形结构 元素存在多对多的相互关系 物理结构 顺序存储 逻辑上相邻的节点物理上也相邻【查询效率高,插入删除效率低】 链式存储 逻辑上相邻的节点物理上不一定相邻【插入删除效率高,查询效率低】 索引存储 除建立存储结点信息外,还建立附加的索引表来标识结点的地址。 用结点的索引号来确定结点存储地址,其优点是检索速度快,缺点是增加了附加的索引表,会占用较多的存储空间。 散列存储 又称hash存储

模拟测试66

我们两清 提交于 2019-12-01 06:38:12
T1:   每行每列都可以交换,其实就是错位排列。   写出递推式,打个高精就行了。     $f_n=(f_{n-1}+f_{n-2})*(n-1)$。   时间复杂度$O(nc)$。 T2:   可以暴力用bitsetAC。   直接建图跑拓扑,判断所有点的入度和能到达它的的点数是否相同。   用bitset维护连通集合。   若图Q是传递的,对于P中的每一条边$<u,v>$,一定不存在$u$到$v$的通路,否则与Q传递矛盾。   也就是说,仅当总的图无环,才满足条件。   直接拓扑排序即可。   时间复杂度$O(n^2)$。 T3:   数位DP。 来源: https://www.cnblogs.com/hz-Rockstar/p/11655798.html

排序算法

眉间皱痕 提交于 2019-12-01 06:04:26
#define LENGTH(array) ( (sizeof(array)) / (sizeof(array[0])) ) #define swap(a,b) do{a=a+b;b=a-b;a=a-b;}while(0) //两个数相同时 会导致结果为0 一、插入排序 1、直接插入排序 1 /** 2 ** 直接插入排序(插入到准确的位置) 不利于二分查找 直接遍历 3 ** 时间复杂度:比较和移动和平均时间复杂度为O(n^2) 适合基本有序的序列,此时复杂度接近O(n) 4 ** 空间复杂度:O(1) 5 ** 稳定性:稳定 6 **/ 7 void InsertSort(int a[], int n) 8 { 9 int i, j; 10 for (i = 2; i <=n; i++)//假设第一项已经排好,所以从第二项开始 11 { 12 if (a[i] < a[i - 1])//若此项小于 前面已经排好的最后一项(已排好的最大项) 13 { 14 a[0] = a[i];//0号位置为哨兵节点 15 for (j = i - 1; a[0] < a[j]; j--)//从后 向前查找待插入位置 16 { 17 a[j+1] = a[j];//记录后移 18 } 19 a[j+1] = a[0];//复制到插入的位置 此时a[j]已经是小于a[0]的了 20 } 21 }

模拟测试65

谁说胖子不能爱 提交于 2019-12-01 04:52:24
T1:   枚举$m$的个数,$O(1)$算出有几个$x$符合条件。   这样不仅效率低下,还会算重。   把$m$一定时的所有结果拍在数轴上发现仅当$ym>=lcm(n,m)$时会算重。   枚举到$lcm$即可。   时间复杂度$O(n)$。 T2:   直接统计复杂度太高,考虑换一个思路。   枚举$gcd$,将所有边权为$gcd$倍数的边都连接起来,求树上直径即可。   发现只有边权的因数才会成为$gcd$,所以只枚举约数即可。   维护连接的边和点,一个一个删除。   每条边至多被枚举$\sqrt{v}$次,复杂度可以接受。   时间复杂度$O(n\sqrt{v})$。 T3:   神贪心。   设起点为$s$,终点为$e$,最优决策一定为$s$和$e$中间的边都尽可能经过一次。   由于要到达终点,$s$和$e$外侧的每条边至少被经过两次。   而在向左走的步数一定的情况下,$e$在一定区间内。   枚举$e$的位置,然后用堆维护中间的边,找出最大的几条边,仅走一次。   其他边都要走两次。   时间复杂度$O(nlogn)$。 来源: https://www.cnblogs.com/hz-Rockstar/p/11655732.html