赞
踩
1.算法渐进性态:当问题规模(n)趋近无穷大,称为O(n)= 表达式,取表达式的最高阶无穷大,这个就是运行时间的上界。
问题的上界
问题准确界
问题的下界
问题一:知问题复杂度,求计算机速度提升一定倍数,求同样时间内处理问题规模变为原来多少?
问题:解决某问题有三种算法,复杂性分别为1000N、10N的2次方、2的N次方,在一台机器上可处理问题的规模分别为S1、S2、S3 。若机器速度提高到原来的10倍,问在同样时间内可处理问题的大小如何?
解:设计算机原来速度为v,则提升速度后10v,
问题规模/速度=时间,利用两次处理时间相等但问题规模不同列方程。
原问题规模/原速度 = 新问题规模 / 新速度
则,1000S1 / v = 1000n / ( 10v)
问题二:知问题复杂度,改进复杂度,求提升后,原来问题解决时间。
问题:例2:问题P的算法复杂度为T(n)=n的3次方(毫秒),现改善为T(n)=n的2次方(毫秒)。问原来运行1小时的问题实例,现在要运行多少时间?
解:设计算机速度为v,原来用时为t, 问题规模为n,新用时为t1。
问题规模/速度=时间,利用两次处理速度相等、问题规模相同列方程。
同时利用原来的用时求出问题规模n的大小。
n^3 / t = n^2 / t1
n^3 = 1 hour
n=153
t1 = t / n = 23.5
阶乘函数
- int Factorial(int n)
- {
- if(n==0) return 1;
- return n*Factorial(n-1);
- }
Fibonacci数列
无穷数列1,1,2,3,5,8,13,21,34,55,……。
- int fibonacci(int n)
- {
- if (n <= 1) return 1;
- return fibonacci(n-1)+fibonacci(n-2);
- }
排列问题
整数划分问题
一般递归问题会用非递归方法代替:
1. 可化为非递归方法。
2. 栈模拟。
分治法的基本思想
分治法的设计思想:
1) 将一个难以直接解决的大问题,分割成一些规模较小的子问题;这些子问题互相独立且与原问题相同
2)递归地解子问题
3) 将各个子问题的解合并得到原问题的解
- Divide-and-Conquer(P)
- {
- if ( |P|<=n0) Adhoc(P);
- divide P into smaller subinstances P1 ,P2,... ,Pk;
- for (i = 1;i <= k; i++)
- yi=Divide-and-Conquer(Pi);
- return Merge( yl ,..., yk);
- }
算法时间复杂度
主方法
二分搜索技术
- int BinarySearch(Type a[ ], const Type &x,int n)
- {
- int left=0; int right=n-1;
- while(left<=right){
- int middle=(left+right)/2;
- if(x==a[middle])
- return middle;
- else if(x>a[middle])
- left=middle+1;
- else
- right=middle-1;
- }
- return -1;
- }
棋盘覆盖问题
合并排序
- temlplate <class type>
- void MergeSort(Type a[], int left, int right)
- { if (1eft < right) //至少有2个元素
- {
- int i = (left + right ) /2; //取中点
- MergeSort(a, left, i);
- MergeSort(a, i+1, right);
- Merge(a, b, left, i, right);//从a合并到数组b
- copy(a, b, left, right);//复制回数组a
- }
- }
快速排序算法
- //将>=x的元素交换到右边区域
- //将<=x的元素交换到左边区域
- int Partition(Type a[ ],int p , int r )
- {
- int i=p;
- j=r+1;
- type x=a[p];
- while(true)
- {
- while(a[++i] < x&&i<r);
- while(a[--j] > x);
- if (i>=j ) break;
- swap(a[i],a[j]);
- }
- a[p] = a[j];
- a[ j] = x;
- return j }
-
-
-
- template <class Type>
- void QuickSoft(Type a[], int p, int r)
- {
- if(p<r){
- int q=Partition(a, p, r)
- QuickSort(a, p, q-1); //对左半段排序
- QuickSoft(a, q+1, r); //对右半段排序
- }
- }
-
-
-
- //随机选择基准点、
- template <class Type>
- void randomizedQuickSoft(Type a[], int p, int r)
- {
- if (p<r) {
- int q=randomizedPartition(a, p, r)
- randomizedQuickSort(a, p, q-1); //对左半段排序
- randomizedQuickSoft(a, q+1, r); //对右半段排序
- }
- }
-
- template <class Type>
- int randomizedPartition(Type a[], int p, int r)
- {
- int i=random( p, r)
- swap( a[i], a[p] )
- return Partition (a,p,r)
- }
最接近点对问题
给定平面上n个点,找其中的一对点,使得
在n个点组成的所有点对中,该点对间的距离最小。
线性时间选择
大整数的乘法
Strassen矩阵乘法
矩阵连乘
最大子段和
- int MaxSum(int n, int * a)
- {
- int sum=0, b=0;
- for (int i=1; i<=n; i++) {
- if(b>0) b+=a[i];
- else b=a[i];
- if (b>sum) sum=b;
- }
- return sum
- } //时间和空间复杂度:O(n)
0-1背包
最长公共子序列
最大子段和
- int MaxSum(int n, int * a)
- {
- int sum=0, b=0;
- for (int i=1; i<=n; i++) {
- if(b>0) b+=a[i];
- else b=a[i];
- if (b>sum) sum=b;
- }
- return sum
- } //时间和空间复杂度:O(n)
流水作业调度
图像压缩
贪心算法的基本要素:
(1) 最优子结构
问题的最优解包含子问题的最优解
(2) 贪心选择性质
问题的整体最优解可以通过一系列局部最优选择达到
背包问题
最优装载
哈夫曼编码
构成赫夫曼树的步骤:
1)从小到大进行排序, 将每一个数据,每个数据都是一个节点 , 每个节点可以看成是一颗最简单的二叉树
2)取出根节点权值最小的两颗二叉树
3)组成一颗新的二叉树, 该新的二叉树的根节点的权值是前面两颗二叉树根节点权值的和
4)再将这颗新的二叉树,以根节点的权值大小 再次排序, 不断重复 1-2-3-4 的步骤,直到数列中,所有的数据都被处理,就得到一颗赫夫曼树
哈夫曼编码就是根节点到树叶的编码,左子树为0,右子树为1
背包问题
图的着色:
已知无向图G=(V,E)和m种不同的颜色,如果只允许使用这m种颜色对图G的结点着色,每个结点着一种颜色。问是否存在一种着色方案,使得图中任意相邻的两个结点都有不同的颜色。整数m称为图G的着色数。
背包问题
优先级队列
优先级定义:当前价值+剩余能装的最大价值(上界函数)
分支限界法求解0/1背包问题动画演示(Implementation of 0/1 Knapsack using Branch and Bound)_哔哩哔哩_bilibili
单源最短路径
约束函数:c[i][j]<inf dist[i]+c[i][j] <dist[j]
优先级:节点所对应的当前路长
装载问题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。