编程珠玑
感觉有必要说一下这个编程珠玑了,这本书被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
浙公网安备 33010602011771号