算法竞赛中的时间复杂度选择——以最大连续和问题为例
来源:互联网 发布:机械设计画图软件 编辑:程序博客网 时间:2024/06/07 07:16
最大连续和问题
最大连续和问题。给出一个长度为
n 的序列A1,A2,…,An ,求最大连续和。换句话说,要求找到1≤i≤j≤n ,使得Ai+Ai+1+...+Aj 尽量大。
时间复杂度为n3 的算法
LL maxConSumN3(LL *a, LL n) { tot = 0; conSum = -INF; for(LL i = 0; i < n; i++) { for(LL j = i; j < n; j++) { LL sum = 0; for(LL k = i; k <= j; k++) { sum += a[k]; tot++; } if(sum > conSum) { conSum = sum; } } } return conSum;}
时间复杂度为n2 的算法
LL maxConSumN2(LL *a, LL n) { tot = 0; conSum = -INF; for(LL i = 0; i < n; i++) { LL sum = 0; for(LL j = i; j < n; j++) { sum += a[j]; tot++; if(sum > conSum) { conSum = sum; } } } return conSum;}
时间复杂度为nlog2n 的算法
// 采用分治法// 对半划分// 递归求解左半边和右半边的最大连续和// 递归边界为left=right// 求解左右连接部分的最大连续和// 合并子问题:取三者最大值LL division(LL *a, LL lef, LL righ) { // 递归边界 if(lef == righ) { return a[lef]; } LL center = lef + (righ - lef) / 2; // 左半边最大连续和 LL maxLeftSum = division(a, lef, center); // 右半边最大连续和 LL maxRightSum = division(a, center + 1, righ); // 左连接部分最大和 LL maxLeftConSum = -INF; LL leftConSum = 0; for(LL i = center; i >= lef; i--) { leftConSum += a[i]; tot++; if(leftConSum > maxLeftConSum) { maxLeftConSum = leftConSum; } } // 右连接部分最大和 LL maxRightConSum = -INF; LL rightConSum = 0; for(LL i = center + 1; i <= righ; i++) { rightConSum += a[i]; tot++; if(rightConSum > maxRightConSum) { maxRightConSum = rightConSum; } } return max(max(maxLeftSum, maxRightSum), maxLeftConSum + maxRightConSum);}LL maxConSumNLogN(LL *a, LL n) { return division(a, 0, n - 1);}
时间复杂度为n 的算法
LL maxConSumN(LL *a, LL n) { conSum = -INF; LL sum = 0; tot = 0; for(int i = 0; i < n; i++) { sum += a[i]; tot++; if(sum < 0) { sum = 0; } if(sum > conSum) { conSum = sum; } } return conSum;}
测试主程序
#include <iostream>#include <algorithm>using namespace std;typedef long long LL;const LL INF = 100000000;// 总执行次数LL tot;// 最大连续和LL conSum;// 求最大连续和问题// n^3的算法LL maxConSumN3(LL *a, LL n) { tot = 0; conSum = -INF; for(LL i = 0; i < n; i++) { for(LL j = i; j < n; j++) { LL sum = 0; for(LL k = i; k <= j; k++) { sum += a[k]; tot++; } if(sum > conSum) { conSum = sum; } } } return conSum;}// n^2的算法LL maxConSumN2(LL *a, LL n) { tot = 0; conSum = -INF; for(LL i = 0; i < n; i++) { LL sum = 0; for(LL j = i; j < n; j++) { sum += a[j]; tot++; if(sum > conSum) { conSum = sum; } } } return conSum;}// nlogn的算法// 采用分治法// 对半划分// 递归求解左半边和右半边的最大连续和// 递归边界为left=right// 求解左右连接部分的最大连续和// 合并子问题:取三者最大值LL division(LL *a, LL lef, LL righ) { // 递归边界 if(lef == righ) { return a[lef]; } LL center = lef + (righ - lef) / 2; // 左半边最大连续和 LL maxLeftSum = division(a, lef, center); // 右半边最大连续和 LL maxRightSum = division(a, center + 1, righ); // 左连接部分最大和 LL maxLeftConSum = -INF; LL leftConSum = 0; for(LL i = center; i >= lef; i--) { leftConSum += a[i]; tot++; if(leftConSum > maxLeftConSum) { maxLeftConSum = leftConSum; } } // 右连接部分最大和 LL maxRightConSum = -INF; LL rightConSum = 0; for(LL i = center + 1; i <= righ; i++) { rightConSum += a[i]; tot++; if(rightConSum > maxRightConSum) { maxRightConSum = rightConSum; } } return max(max(maxLeftSum, maxRightSum), maxLeftConSum + maxRightConSum);}LL maxConSumNLogN(LL *a, LL n) { return division(a, 0, n - 1);}// n的算法LL maxConSumN(LL *a, LL n) { conSum = -INF; LL sum = 0; tot = 0; for(int i = 0; i < n; i++) { sum += a[i]; tot++; if(sum < 0) { sum = 0; } if(sum > conSum) { conSum = sum; } } return conSum;}int main() { LL a[] = {-2, 3, 4, 5, -6, 7, -1, 2, 6}; cout << "时间复杂度为N^3的算法:" << maxConSumN3(a, 9); cout << "\t 计算次数为:" << tot << endl; cout << "时间复杂度为N^2的算法:" << maxConSumN2(a, 9); cout << "\t 计算次数为:" << tot << endl; tot = 0; cout << "时间复杂度为NLogN的算法:" << maxConSumNLogN(a, 9); cout << "\t 计算次数为:" << tot << endl; cout << "时间复杂度为N的算法:" << maxConSumN(a, 9); cout << "\t\t 计算次数为:" << tot << endl; return 0;}
输出结果为
时间复杂度为N^3的算法:20 计算次数为:165时间复杂度为N^2的算法:20 计算次数为:45时间复杂度为NLogN的算法:20 计算次数为:29时间复杂度为N的算法:20 计算次数为:9Process returned 0 (0x0) execution time : 0.196 sPress any key to continue.
算法竞赛中的时间复杂度选择
假设机器速度是每秒
表还给出了机器速度扩大两倍后,算法所能解决规模的对比。可以看出,
不过需要注意的是,上界分析的结果在趋势上能反映算法的效率,但有两个不精确性: 一是公式本身的不精确性。例如,“非主流”基本操作的影响、隐藏在大O记号后的低次项和最高项系数;二是对程序实现细节与计算机硬件的依赖性,例如,对复杂表达式的优化计算、把内存访问方式设计得更加“cache友好”等。在不少情况下,算法实际能解决的问题规模与表所示有着较大差异。
尽管如此,表还是有一定借鉴意义的。考虑到目前主流机器的执行速度,多数算法竞赛题目所选取的数据规模基本符合此表。例如,一个指明
0 0
- 算法竞赛中的时间复杂度选择——以最大连续和问题为例
- 【编程珠玑-读书笔记】算法设计技术—以求解"最大连续子序列和"为例
- 以最大连续和为例的算法分析
- 最大流Dinic算法实现——以《算法竞赛入门经典——训练指南》为例
- 求数组中连续最大和值,时间复杂度为O(n)
- 最大连续子序列和 HDU 1231 (时间复杂度为O(n))
- MIT:算法导论——2.渐近符号、递归及解法_和连续子数组的最大和、主方法/主定理求时间复杂度
- 数组连续子序列的最大的和-四种算法,四种时间复杂度
- 数组连续子序列的最大的和;四种算法,四种时间复杂度
- 算法复杂度——时间复杂度和空间复杂度
- 算法复杂度——时间复杂度和空间复杂度
- 算法复杂度——时间复杂度和空间复杂度
- 算法复杂度——时间复杂度和空间复杂度
- 算法复杂度——时间复杂度和空间复杂度
- 算法复杂度——时间复杂度和空间复杂度
- 算法中的时间复杂度和空间复杂度
- 经典算法——连续子数组最大和问题
- 求最大连续子列和的算法和时间复杂度的分析(包含四种不同时间复杂度的算法)
- spring mvc框架整个执行过程,从输入http url,到action映射,再到action处理,返回jsp文件,解析jsp文件,然后渲染, 到返回给浏览器展示结果
- 【Leetcode】Evaluate Reverse Polish Notation
- ARC内存管理及强弱指针(二)
- 【Leetcode】Reverse Words in a String
- 平时的一些总结--ing
- 算法竞赛中的时间复杂度选择——以最大连续和问题为例
- JavaScript 标签自定义属性
- 【Leetcode】Decode Ways
- 实习入职第八天:MediaPlayer使用中最重要的知识点
- JdbcTemplate详解-1
- 二叉树的非递归插入和遍历
- 欢迎使用CSDN-markdown编辑器
- python:网络爬虫入门经验总结大大大大全
- virtualbox上安装centos6.5以及安装Java,redis,hadoop等等常用开发工具