1.概念:概念这个东西太有深度了,目前还没有掌握。通过实例来了解吧。
2.例1:1.图书馆放书问题。遇到这种问题,不仅要考虑如何放,还要考虑如何拿,不能只顾放的时候轻松,正所谓前人栽树,后人乘凉。在遇见问题是,一定要思考全。
3.解决问题的效率:a.跟数据的组织方式有关。
b.跟空间的利用效率有关。
比如实现一个函数PrintN。我们可以用for循环实现,也可以用递归实现。但当n过大时(比如100000),递归实现就有可能报错。
4.例2:计算多项式在定点x的值,有两种方法:a.total +=a[i]*(pow,x);
b.p = a[i-1]+ x * p;
明显,第二种方法更好,第一个的时间复杂度为n的三次方,而第二个仅为n。这个差距是非常恐怖的。
5.复杂度从1,logn,n,nlogn,n的平方,n的立方,2的n次方,n的阶层依次上升,所以我们要尽可能把算法设计成靠前的。
6.最后这是第一章有关算法设计非常好的实例,求最大子列和的问题。有四种方法,可以很直观的感受的算法的魅力,真的那些设计算法的人,我把花半天才能理解一个算法,而他们却能把他们写出来,真是太厉害了(我花半天应该很大一部分原因是因为基础不好,加上脑子反应慢)。
最后附上四种不同方法的解题代码:
a.这是第一种最笨的方法,不过也是我能想出来的方法。
void Max (int a[],int N)
{
int this,max = 0;
int i,j,k;
for (i = 0;i < N;i++){
for (j = i;j < N;j++){
this = 0;
for (k = i;k <= j;k++){
this += a[k];
}
printf("this is %d
",this);
if (this > max) max = this;
}
}
printf("max is %d
",max);
}
b.第二章方法就是简化了一些重复的步骤,却可以节省n倍的时间。
void Max1 (int a[],int n)
{
int this,max;
int i,j;
for ( i = 0; i < n;i++){
this = 0;
for (j = i;j < n;j++){
this += a[j];
if (this > max) max = this;
}
}
printf("max is %d
",max);
}
c.这是用了分而治之的方法,先分再和,用了递归的思想,我认为递归这个很打脑壳,可能是因为脑子笨的原因加上代码写少了。
#include <stdio.h>
int max (int a, int b, int c)
{
int temp = a;
if (a < b) {
temp = b;
}
if (temp < c) {
temp = c;
}
return temp;
}
int find (int list[], int left, int right)
{
int MLS,MRS;
int MLBS,MRBS;
if (left == right){
if (list[left] > 0){
return list[left];
}else{
return 0;
}
}
int center = (right + left) / 2;
MLS = find (list,left,center);
MRS = find (list,center+1,right);
MLBS = 0;
MRBS = 0;
int i;
int LBS = 0;
int RBS = 0;
for (i = center;i >= left;i--){
LBS += list[i];
if (LBS >MLBS ){
MLBS = LBS;
}
}
for (i= center +1;i <= right;i++){
RBS += list[i];
if (RBS > MRBS){
MRBS = RBS;
}
}
return max(MLS,MRS,MLBS+MRBS);
}
int Div(int list[],int n)
{
find (list,0,n-1);
}
d.这是最nb的解法,时间复杂度仅为n,也就是说,仅仅是花了把每个数读一遍的时间,就解出来了,真心佩服。
void Max2 (int a[], int n){
int this,max;
int i;
for (i = 0; i < n;i++){
this += a[i];
if(this > max){
max = this;
}else {
this = 0;
}
}
printf("max is %d
",max);
}
第一章的总结就写到这里吧,期待第二章!