NOIP初赛中的算法复杂度问题学习笔记
- 定义
这个定义没什么好说的,百度启动。
存在常数 c,使得当 N >= c 时 T(N) <= f(N),表示为 T(n) = O(f(n))
意思就是O(f(n))表示的是T(n)的增长速度,由于T(n)可以看做是渐进于O(n),所以这也叫做算法时间复杂度的渐进表示法。
-
做题技巧
考试中做题还是最重要的。
- 抠脚题
对于一些简单的一批的顺序结构程序,数循环就够了。
举个栗子:
for(int i = 0; i < n; ++i)
{
printf("我是校草");//基本语句时间复杂度看做O(1)
}
这里有n个O(1),所以算法时间复杂度是O(n)。如果我们暴力套一堆循环。
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
for(int k = 0; k < n; ++k)
{
printf("你是校花");
}
}
}
那么很显然,算法复杂度就是O(n³)。
再来一个,要注意这里内循环的初始值是i。
for(int i = 0; i < n; ++i)
for(int j = i; j < n; ++j)
printf("校草喜欢校花");
很显然,内循环运行了log2(n)\log_2(n)log2(n)次,所以T(n)=O(logn)T(n) = O(\log n)T(n)=O(logn)
对付这种程序数循环个数就够了。很显然联赛不会考这么简单的 。
- 递归程序分析
long fun(int n) {
if (n <= 1) {
return 2;
} else {
return fun(n - 1) + fun(n - 2);
}
}
好,你厉害,一眼看出是斐波那契数列然后默写了个复杂度。那看不出来岂不完蛋了!其实在赛场上可以手推得,有高中的数学基础就可以了。
这个时间复杂度可以写成一个递推式:
T(0)=T(1)=1T(0) = T(1) = 1T(0)=T(1)=1
T(n)=T(n−1)+T(n−2),n≥2T(n) = T(n-1) + T(n-2) ,n\geq2T(n)=</