分治法学习记录

来源:互联网 发布:公司网络优化方案 编辑:程序博客网 时间:2024/05/06 16:57

分治法学习记录

#include <iostream>#include <vector>using namespace std;int maxsum (vector<int> ivec, vector<int>::iterator start, vector<int>::iterator end){    if (start == end) return *start;    /*检查序列是否为空或仅有一个元素*/    vector<int>::iterator mid = start + (end - start)/2;    int **maxs** = max(maxsum(ivec, start, mid), maxsum(ivec, mid, end));    /*若最大连续和不过中间*/    int Lsum = 0, Rsum = 0, temp = 0;;    vector<int>::iterator iter = mid-1;    while (iter-- >= start) Lsum = max(Lsum, temp += *iter);    iter = mid; temp = 0;    while (iter++ <= end) Rsum = max(Rsum, temp += *iter);    /*由中间开始分别向两边延伸求求最大连续和序列*/    return max(maxs, Lsum+Rsum);}int main(int argc, const char * **argv**[]) {    vector<int> ivec;    int num = 0;    while(cin >> num)        ivec.push_back(num);    cout << maxsum(ivec, ivec.begin(), ivec.end()) << endl;    return 0;}

先说一点:看递归应该广度优先遍历!!!
这是我被坑懵逼了无数次得出的结论。。。。。
追求这个函数最后递归成啥样的人都死的很难看。。。。
话说回来,这程序是因为我实在看不过眼书上用数组实现的代码,于是改成了用vector实现(其实就是改了几个类型和变量名),然而我不能理解的是,
为什么特么的会有死循环???
为什么递归的时候迭代器出界了???
我不能理解啊喂!!!!(╯‵□′)╯︵┻━┻,明明和原代码一毛一样!!!!

咳咳回到正题,分治法:划分,递归解决,合并序列。问题最大的是合并序列,很多情况下这个问题一旦被分开了就合不起来了,书上的大部分例子在刚看到的时候都有这感觉。这其实是人对于递归有一定误解的情况下发生的情况,就像上面说的,别看到递归就想着“下一层是啥情况?”“再下面一层是啥情况?”,一般来说,看递归,预先了解这函数是干嘛的,得到功能后直接把功能带入递归代码中,不要硬想着下一层发生了啥,比方说这几行:

    while (iter-- >= start) Lsum = max(Lsum, temp += *iter);    iter = mid; temp = 0;    while (iter++ <= end) Rsum = max(Rsum, temp += *iter);

真往下层看根本不是个头,直接从代码介绍中获得“这函数获取这一段中的最大连续和”,代入后即可获得注释中写的内容。
另外,这个程序中用“左闭右开”的集合范围,好处是在处理“数组分割”时比较自然,区间[x,y)被分为[x,m),[m,y)两部分,不需要在任何地方加减一。
还有一个细节:x+(y-x)/2来获取序列的中间值,尽管在数学上这和(x+y)/2结果一样,但计算机计算时会向下取整,会更自然的分成上面说的形式。

0 0
原创粉丝点击