【算法竞赛入门经典】8.1 最大连续子序列和
2018-02-10 14:58
573 查看
共提供fun1()~fun5()五种方法。
fun1()为暴力
fun2()使用了Sn进行优化,每次计算区间i~j的时候就不需要逐个累加了
fun3()是典型分治法,假设三种情况:起末位置均在mid往左,起末位置均在mid往右,起点在mid往左,终在mid往右。
fun4()是动态规划,使用了状态转移方程
fun5()是fun4()的空间优化版本,不需要开数组了。
fun1()为暴力
fun2()使用了Sn进行优化,每次计算区间i~j的时候就不需要逐个累加了
fun3()是典型分治法,假设三种情况:起末位置均在mid往左,起末位置均在mid往右,起点在mid往左,终在mid往右。
fun4()是动态规划,使用了状态转移方程
sum[i] = max{sum[i-1]+dat[i],dat[i]}
fun5()是fun4()的空间优化版本,不需要开数组了。
#include<iostream> #include<algorithm> #include<ctime> using namespace std; int dat[10] = { -10,1,2,3,4,-5,-23,3,7,-21 }; int fun1() {//暴力求解 int maxi = dat[0]; for (int i = 0; i < 10; i++) { for (int j = i; j < 10; j++) { int sum = 0; for (int k = i; k <= j; k++) { sum += dat[k]; } maxi = max(maxi, sum); } } return maxi; } int fun2() {//sum和优化 int sum[11], maxi = dat[0]; sum[0] = 0; for (int i = 1; i <= 10; i++) sum[i] = dat[i - 1] + sum[i - 1]; for (int i = 0; i < 10; i++) { for (int j = i + 1; j < 10; j++) { int temp = sum[j] - sum[i]; maxi = max(maxi, temp); } } return maxi; } int fun3(int left,int right) {//分治法 if (right - left == 1) return dat[left]; int Lmax, Rmax, mid, v, sidemax; mid = (left + right) / 2; sidemax = max(fun3(left, mid), fun3(mid, right)); v = 0; Lmax = dat[mid - 1]; for (int i = mid - 1; i >= left; i--) { v += dat[i]; Lmax = max(Lmax, v); } v = 0; Rmax = dat[mid]; for (int i = mid; i < right; i++) { v += dat[i]; Rmax = max(Rmax, v); } return max(sidemax, Lmax + Rmax); } int fun4() {//dp;sum[i] = max{sum[i-1]+dat[i],dat[i]}. (sum[i]记录以a[i]为子序列末端的最大序子列连续和) int sum[10], maxi; sum[0] = maxi = dat[0]; for (int i = 1; i < 10; i++) { sum[i] = max(sum[i - 1] + dat[i], dat[i]); maxi = max(maxi, sum[i]); } return maxi; } int fun5() {//对dp的优化,不需要开数组了 int maxi, temp; maxi = temp = dat[0]; for (int i = 1; i < 10; i++) { if (temp > 0) temp += dat[i]; else temp = dat[i]; if (temp > maxi) maxi = temp; } return maxi; } int main() { clock_t t1, t2; t1 = clock(); cout << fun1() << endl; t2 = clock(); cout << t2 - t1 << " ms" << endl << endl; t1 = clock(); cout << fun2() << endl; t2 = clock(); cout << t2 - t1 << " ms" << endl << endl; t1 = clock(); cout << fun3(0, 10) << endl; t2 = clock(); cout << t2 - t1 << " ms" << endl << endl; t1 = clock(); cout << fun4() << endl; t2 = clock(); cout << t2 - t1 << " ms" << endl << endl; t1 = clock(); cout << fun5() << endl; t2 = clock(); cout << t2 - t1 << " ms" << endl << endl; getchar(); getchar(); return 0; }
相关文章推荐
- 算法竞赛入门经典:第六章 数据结构基础 6.9 根据二叉树的后序和中序确定前序序列
- 算法之路二:刘汝佳算法竞赛入门经典 3.10环状序列 UVa1584
- 环状序列 算法竞赛入门经典
- 算法竞赛入门经典习题2-4 子序列的和(subsequence)
- 20160321 UVa RUJIA 算法竞赛入门经典:镜像回文,生成元,环状序列
- 【算法竞赛入门经典】树的最大独立集、树的唯一性问题 例题9-13 UVa1220
- (枚举)算法竞赛入门经典(7.1.2)最大乘积
- 算法竞赛入门经典2.5 2-4子序列的和
- 子序列的和(subsequence) 算法竞赛入门经典
- (枚举)算法竞赛入门经典(7.1.2)最大乘积
- 算法竞赛入门经典 第二版 习题5-2 Ducci序列 Ducci Sequence uva1594
- 经典字符串算法 “最长上升子序列,最大连续子序列和,最长公共子串”
- 算法竞赛入门经典 第三章 uVa1225 - Digit Counting
- 【算法竞赛入门经典第二版学习】第三章习题
- 算法竞赛入门经典: 第四章 函数与递归 4.2组合数
- 算法竞赛入门经典 2.1 for 循环
- 算法竞赛入门经典第6章例题(2):二叉树部分+四分树
- 算法竞赛入门-习题3-9 子序列(All in All, UVa 10340)
- 算法竞赛入门经典 习题3-1 分数统计(stat)
- 【索引】算法竞赛入门经典-第8章 高效算法设计