Solution to CLRS Chapter 4
来源:互联网 发布:mac鼠标能点右键吗 编辑:程序博客网 时间:2024/06/16 21:18
这一章主要介绍了几个divide-and-conquer的例子,并且引入了对递归算法的复杂度进行刻画的数学工具,这章工具数学性很强,所以数学部分打算以后遇到了再回头来看,不过那个master theorem真的好方便啊!
4.1-1
用divide-and-conquer处理最大连续子序列和,在conquer的时候,涉及3个sum之间的比较:
left-sum,right-sum,cross-sum,其中cross-sum必须要包含a[mid],a[mid+1]两个点,由于整个序列都是负数,所以cross-sum是最小的(加的越多越下),先排除,这样,剩下left-sum和right-sum本质上是就是找左右区间中最大的那个元素,所以,最后的结果一定返回的是[1…n]中,最大的负数
4.1-2
brute-force算法,就是要枚举每一种买股票的可能,这可以通过枚举买进时间i,卖出时间j来实现,这样的复杂度,已经达到theta(n^2)了,所以,在确定了区间[i,j]的时候,需要一个常数级算法,求出区间[i,j]的和,这个可以用一个预处理,得到一个sum[]数组,sum[i]表示前i项的和,那么区间[i,j]的和就可以表示成sum[j]-sum[i-1]
pseudocode:
BRUTE-FORCE-MAXIMUN-SUBARRAY sum[0] = 0; for i = 1 : N sum[i] = sum[i-1] + a[i] maxSum = -INF for i = 1 : N for j = i : N if sum[j] - sum[i-1] > maxSum maxSum = sum[j] - sum[i-1] startPoint = i; endPoint = j; return (maxSum, startPoint, endPoint)
4.1-3
这题是判断brute-force算法和用divide-and-conquer paradigm的性能的分界点,然后用这个来优化recursive版本算法的性能,换角度说也就是coarsen the leaves,这个思想在之前的merge sort 也用到了。
下面用C++实现一下这个比较:(比较方法是测试规模为10000的数据)
我电脑测试的时候,从n=1开始,就是divide-and-conquer更加优秀………………
C++ code:
#include <iostream>#include <cstdlib>#include <ctime>#include <cstring>#include <cstdio>using namespace std;const int INF = 0x7fffffff;const int MAX_N = 1000000 + 3;int A[MAX_N];int CrossSum (int *A, int l, int mid, int r) { int left_max = -INF, left_sum = 0; int right_max = -INF, right_sum = 0; for (int i = mid; i >= l; --i) { left_sum += A[i]; left_max = max(left_max, left_sum); } for (int i = mid+1; i <= r; ++i) { right_sum += A[i]; right_max = max(right_max, right_sum); } return left_max + right_max;}int RecursiveMaxSub (int *A, int l, int r) { if (l == r) return A[l]; int mid = (l + r) / 2; int left_sum = RecursiveMaxSub(A, l, mid); int right_sum = RecursiveMaxSub(A, mid+1, r); int cross_sum = CrossSum(A, l, mid, r); int maxSum = left_sum; if (right_sum > maxSum) maxSum = right_sum; if (cross_sum > maxSum) maxSum = cross_sum; return maxSum;}int sum[MAX_N];int BruteForceMaxSub (int *A, int N) { int i, j, maxSum = -INF; sum[0] = 0; for (i = 1; i <= N; ++i) sum[i] = sum[i-1] + A[i]; for (i = 1; i <= N; ++i) for (j = i; j <= N; ++j) if (sum[j] - sum[i-1] > maxSum) maxSum = sum[j] - sum[i-1]; return maxSum;}void getNewArray(int* A, int n) { for (int i = 1; i <= n; ++i) A[i] = rand() % 1000 - 500;}int main (int argc, char* argv[]) { int n = 9; srand(time(NULL)); getNewArray(A, n); //randomly get a new array int time1 = clock(); int result1 = BruteForceMaxSub(A, n); time1 = clock() - time1; int time2 = clock(); int result2 = RecursiveMaxSub(A, 1, n); time2 = clock() - time2; if (result1 != result2) cout << "Algorithm Error!" << endl; //cout << "brute-force: " << time1 / CLOCKS_PER_SEC << " s divide-and-conquer: " << time2 / CLOCKS_PER_SEC << " s" << endl; cout << "brute-force: " << time1 << " clocks divide-and-conquer: " << time2 << " clocks" << endl; return 0;}
4.1-4
这个挺简单的,不允许empty array只会出现在所有的元素都是负数的情况下,由4.1-1知这种情况下,返回的一定是元素中最大的负数,所以,只要加一个判断-如果MaxSub返回的结果是负数,那么显然这个结果不如选取一个空串得到0,所以将所以返回负数的情况,特判改成0就可以了。
4.1-5
这道题就是动态规划的思想吧,hdu1003 Max Sum 就是这个题目,还有一个升级版是hdu1024
这里给出升级版:
#include <cstdio>#include <cstring>#include <algorithm>using std::max;const int MAX_N = 1000000 + 6;const int INF = 0x7fffffff;int dp[MAX_N];int a[MAX_N];int rmax[MAX_N];int main (int argc, char* argv[]) {#ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin);#endif int n, m; while (scanf("%d%d", &m, &n) != EOF) { for (int i = 1; i <= n; ++i) scanf("%d", a + i); memset(dp, 0, sizeof(dp)); memset(rmax, 0, sizeof(rmax)); int ans = -INF; int i, j; for (i = 1; i <= m; ++i) { ans = -INF; for (j = i; j <= n; ++j) { dp[j] = max(dp[j-1], rmax[j-1]) + a[j]; rmax[j-1] = ans; ans = max(ans, dp[j]); } } printf("%d\n", ans); } return 0;}
这一章有点奇怪,但感觉并不是无用,回头再看
4.2-1
4.2-2
4.2-3
4.2-4
4.2-5
4.2-6
4.2-7
以后遇到相关的计算再来看,现在对这个没什么概念
- Solution to CLRS Chapter 4
- Solution to CLRS Chapter 2
- Solution to CLRS Chapter 3
- Solution to CLRS Chapter 5
- Solution to CLRS Chapter 6
- Solution to CLRS Chapter 7
- Solution for Exercise 15.1-2 of CLRS
- CLRS (Introduction to Algorithms 2nd) reanding notes 4
- My solution to cs224n assignment1(3-4)
- 算法导论Introduction to Algorithms(CLRS)
- Introduction to Algorithm(chapter 3 and 4)
- Solutions to <Learning jQuery> Chapter 4
- solution to Steps
- Solution to DeadLock
- Solution for exercise 1.1-4 in Introduction to Algorithms
- 2011-03-03 CLRS Chapter 5 Randomized Algorithms 随机化的算法
- How to get a solution?
- Solution Manager 2.1 To 7.1
- 5.17学习内容 android判断软键盘状态、系统键盘监控、生成中间logo的二维码
- stk6.1安装方法
- poj 1651 区间dp
- 1029. 旧键盘(20)
- poj 2446 二分图最大匹配 匈牙利算法
- Solution to CLRS Chapter 4
- C++ Primer:第八章:IO库(续)
- 第十一周项目一 是春哥啊
- 四十七、多态性:运算符重载为类的友元函数
- 动态规划(线性类)--ones 唯“一”运算
- 每天拿出来2小时浪费(文/王路) 作者: 王路
- uva 11991 Easy Problem from Rujia Liu? Data Structure
- 答微信产品经理假面试题
- Java遇见的一些概念问题