首页 > 学院 > 开发设计 > 正文

分治法学习记录

2019-11-11 04:03:40
字体:
来源:转载
供稿:网友

分治法学习记录

#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结果一样,但计算机计算时会向下取整,会更自然的分成上面说的形式。


上一篇:1105: 这里有一张图

下一篇:文章标题

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表