编程珠玑

感觉有必要说一下这个编程珠玑了,这本书被n个人推荐过,但是还是有n^3个计算机同学不知道它的存在。这是本短小精悍的书籍,有必要推荐给大家。

今天看第八章的时候(算法的设计艺术),哇,牛人太多了,还是我太笨了。废话少说:

我在读起原理的时候看到两个很经典的总结:扫描算法:与数组相关的问题经常可以通过思考“如何将x[0..i-1]的解扩展为x[0..i]?

累积:使用一个累积表,表中的第i个元素的值为x中的前i个元素的和;此法可以解决有限问题。比如:业务要统计3月到10月的销售额,可以将10月的额份减去2月份的额份即是结果了。此法很牛逼啊。

在一批个数为n的数据中,选出一批子向量,使其数据和最大。这个问题有四种方法的:

1.双重循环了:

for  i=[0..n] 

   for j=[i..n]

       sum+=x[j];

 maxsum=max(maxsum,sum);

2.想将前i项的和计算出来,存储起来。

 for i=[0..n]

  cur[i]+=x[i];

然后再利用x[i..j]=cur[j]-cur[i-1];

 for i=[0..n]

  for j=[i..n]

    sum=cur[j]-cur[i-1];

maxsum=max(sum,maxsum);

3.分治法:将源数组分成两块,最大的子向量和,要么在左边,要么在右边,要么在中间了。

 maxdivide( l,h)

{

if(l>h) return 0;

if(l==h) return max(0,x[1]);

m=(l+h)/2;

for i=[m..0]

 sum+=x[i];

lmax=max(lmax,sum);

for j=[m..h];

sum+=x[j];

rmax=max(rmax,sum);

return max(rmax+lmax,,maxdivide(0,m),maxdivide(m+1,u));

}

4.牛逼的方法出现了:maxend 为赋值前前i-1的最大子向量的和,赋值之后即为结束位置为I 的最大子和

for i=[0..n]

maxend=max(maxend+x[i],0);//好好体会

maxsofor=max(maxsofor,maxend);

应用案例:

累积法:比如查找总和总是最接近0的子向量 cur[u]-cur[j-1]~~0

posted on 2011-03-09 22:26  kevinferry  阅读(356)  评论(0)    收藏  举报