【演算法設計與分析】6、最大欄位和
/** * 書本:《演算法分析與設計》 * 功能:若給定n個整陣列成的序列a1, a2, a3, ......an, 求該序列形如ai+a(i+1)+......+an的最大值 * 檔案:MaxSum.cpp * 時間:2014年11月30日17:37:26 * 作者:cutter_point */ #include <iostream> using namespace std; //方法一: /* 簡單的解決方式時間複雜度是O(n^3) 解決方法就是一般演算法 */ //給我一串數字元素,找到最大的欄位和的那個欄位 //n是這串數字的個數, a是這串數字, besti是最佳的開始加的位置,bestj是最佳的結束位置 int MaxSum(int n, int *a, int& besti, int& bestj) { int sum = 0; //統計得到的最大值,從中選出最大的 for (int i = 1; i <= n; ++i) //從第一個數字開始,到最後一個數 { for (int j = i; j <= n; ++j) //j是表明要在i開始到j的累加範圍 { int thissum = 0; //一這個i起始的開始向後加到j的當前這個i之後對應的最大欄位和 //開始從i開始往後一個一個的加,並把選到最大的那個欄位和 for (int k = i; k <= j; ++k) //重這個i加到j(j這個值每個都會試到) thissum += a[k]; if (thissum > sum) { sum = thissum; //把新的最大值放給要返回的值 besti = i; //最好的起始位置給記住 bestj = j; //最好的結束位置給記住 } } } return sum; //返回最大值 } //方法二: /* 簡單的解決方式時間複雜度是O(n^2) 解決方法就是運用一個數學公式i到j的累加 = 第j個數 + 前面的j-1個和 */ //給我一串數字元素,找到最大的欄位和的那個欄位 //n是這串數字的個數, a是這串數字, besti是最佳的開始加的位置,bestj是最佳的結束位置 int MaxSum2(int n, int *a, int& besti, int& bestj) { int sum = 0; //還是這個是得到最終的結果 //還是從第i個開始向後加j,知道所有的i都得到比較 for (int i = 1; i <= n; ++i) { //這個i對應的最大值是 int thissum = 0; for (int j = i; j <= n; ++j) { thissum += a[j]; //從i開始累加 if (thissum > sum) //只要找到比上一個的sum大的就代入 { sum = thissum; besti = i; bestj = j; } } } return sum; } //方法三: /* 簡單的解決方式時間複雜度是O(nlogn) 解決方法就是運用分治遞迴的方式 就是最優子結構是 a[1:n]的最大欄位是a[1:n/2]相同的 a[1:n]的最大欄位是a[n/2+1:n]相同的 a[1:n]的最大欄位和為i到j的累加,且i和j分別在中點的兩端 */ //給我一串數字元素,找到最大的欄位和的那個欄位 //a裡面是這一串數字,left是這串數字的開始位置,right是這串數字的結束位置 int MaxSubSum(int *a, int left, int right) { int sum = 0; //還是用來計數最大值 //如果只有一個數了,那麼就開是比0大還是比0小,大就是這個數了,小那麼還是不用加了就等於0把 if (left == right) //還有這一步是為了方便遞迴 sum = a[left] > 0 ? a[left] : 0; else //如果不止一個數的話 { int center = (left + right) / 2; //1、得到左邊的最大值 int leftsum = MaxSubSum(a, left, center); //2、得到右邊的最大值 int rightsum = MaxSubSum(a, center + 1, right); //3、如果左邊和右邊夾在一起合成的欄位和的話 //用一個數來表示左邊正數的和 int s1 = 0; //從右到左得到最大的那個值 int lefts = 0; //依次加上左邊的下一個值得和 for (int i = center; i >= left; --i) //從中間向左邊疊加,為何和右邊的合併所以必須這樣加 { lefts += a[i]; //依次加到lefts裡面 if (lefts > s1) s1 = lefts; //如果這個加起來的和,從右到左得到最大的那個值 } //右邊同上 int s2 = 0; //從左到右得到最大的那個值 int rights = 0; //依次加上右邊的下一個值得和 for (int i = center + 1; i <= right; ++i) //從中間向右邊疊加,為何和左邊的合併所以必須這樣加 { rights += a[i]; //依次加到lefts裡面 if (rights > s2) s2 = rights; } //第三種方式的和是 sum = s1 + s2; //比較三種方式的大小,選出最大的那個 if (sum < leftsum) sum = leftsum; if (sum < rightsum) sum = rightsum; } return sum; } //迭代結束之後得到最大值的方式 //n是數字的個數,a是這串數字的長度 int MaxSum3(int n, int *a) { return MaxSubSum(a, 1, n); } int main() { int a[] = { 0, -1, 7, -3, -3, 5, -2, 7 }; //得到陣列的長度 int n = sizeof(a) / sizeof(*a)-1; int besti = 0, bestj = 0; cout << "這串數字是:" << endl; for (int i = 1; i <= n; ++i) cout << a[i] << " "; cout << endl; cout << "最長欄位和是:" << MaxSum(n, a, besti, bestj); cout<< " 從" << besti << "到" << bestj << endl; cout << "最長欄位和是:" << MaxSum2(n, a, besti, bestj); cout << " 從" << besti << "到" << bestj << endl; cout << "最長欄位和是:" << MaxSum3(n, a)<<endl; return 0; }
相關推薦
【演算法設計與分析】6、最大欄位和
/** * 書本:《演算法分析與設計》 * 功能:若給定n個整陣列成的序列a1, a2, a3, ......an, 求該序列形如ai+a(i+1)+......+an的最大值 * 檔案:MaxSum.cpp * 時間:2014年11月30日17:37:26 * 作者:cu
【演算法設計與分析】貪心策略——最佳郵局設定問題
//總是感覺生活很空虛,就只能寫寫部落格看看書上上課這樣子。想出去,去一個遙遠的地方。先來看一下題目:有n戶人家坐落在從西向東的一條街上。從街西頭向東數,第i戶的房子與街西頭的距離是H[i]米,(1≤i≤n), H[1]< H[2] < H[3] … < H
【計算機演算法設計與分析】——SVM
一.簡介 支援向量機(support vector machines)是一種二分類模型,它的目的是尋找一個超平面來對樣本進行分割,分割的原則是間隔最大化,最終轉化為一個凸二次規劃問題來求解。由簡至繁的模型包括: (1)當訓練樣本線性可分時,通過硬間隔最大化,學習一個線性可分支援向量機;(2)當訓練樣本近似
【演算法設計與分析作業題】第十一週:20. Valid Parentheses
題目 C++ solution class Solution { public: bool isValid(string s) { stack<char> cstack; for (int i = 0; i < s.si
【計算機演算法設計與分析】——NP
時間複雜度 時間複雜度並不是表示一個程式解決問題需要花多少時間,而是當問題規模擴大後,程式需要的時間長度增長得有多快。也就是說,對於高速處理資料的計算機來說,處理某一個特定資料的效率不能衡量一個程式的好壞,而應該看當這個資料的規模變大到數百倍後,程式執行時間是否還是一樣,或者也跟著慢了數百倍
【演算法設計與分析作業題】第二週:1. Two Sum
題目 C++ solution class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { ve
【演算法設計與分析作業題】第九周:17. Letter Combinations of a Phone Number
題目 C++ solution class Solution { public: vector<string> letterCombinations(string digits) { vector<string>
歸併排序和快速排序比較【演算法設計與分析實驗報告】
下面的原始碼是修改的了時間差精確到了納秒級別的了,但是還是感覺很有誤差。無論怎麼測,總是快排比歸併快,即使是測試資料的陣列長度在10以內。 前面一樣的程式寫的是時間精確到微秒級的,陣列長度大概在一萬以內的,就是歸併排序快了,大於這個長度的快速排
【演算法設計與分析作業題】第十週:19. Remove Nth Node From End of List
題目 C++ solution /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListN
『嗨威說』演算法設計與分析 - PTA 數字三角形 / 最大子段和 / 編輯距離問題(第三章上機實踐報告)
本文索引目錄: 一、PTA實驗報告題1 : 數字三角形 1.1 實踐題目 1.2 問題描述 1.3 演算法描述 1.4 演算法時間及空間複雜度分析 二、PTA實驗報告題2 : 最大子段和 2.1 實踐題目 2.2 問題描述 2.
【MySQL 線上 BUG 分析】之 多表同欄位異常:Column ‘xxx’ in field list is ambiguous
一、生產出錯! 今天早上11點左右,我在工作休息之餘,擼了一下貓。突然,工作群響了,老大在裡面說:APP出錯了! 媽啊,這太嚇人了,因為只是說了出錯,但是沒說錯誤的資訊。所以我趕緊到APP上看看。 這果然是出錯了,而且還是簡單而粗暴的500,太嚇人了。 二、本地趕緊除錯起來! 既然線上出錯了,我們又不
Maximum sum【最大欄位和變式】
【題目描述】 對於給定的整數序列A={a1,a2,…,an}A={a1,a2,…,an},找出兩個不重合連續子段,使得兩子段中所有數字的和最大。我們如下定義函式 d(A): 我們的目標就是求出d(A)。 【輸入】 第一行是一個整數T(≤30),代表一
演算法 | 最大欄位和
#include <stdio.h> int a[100001],dp[100001]; int main() { int T,n; while(~scanf("%d",&n)) {
演算法優化:最大欄位和,雙指標遍歷(n^2),分治法(nlogn),動態規劃(n)
最大欄位和,有點類似與最長公共子序列,這裡是求連續一段求和最大的一段,比如[-2,11,-4,-4,13,-5,-2]最大求和的連續一段為11,-4,-4,13,和為16. 最基本的雙針模型遍歷,兩個指標,分別代表最大和序列的起始和終止,演算法時間複雜度O(n^2) # 以下演算法時
求陣列最大欄位和最簡潔有效的演算法
直接上程式碼:public static int max(int[] a){ int max = 0;int zmax = 0; for (int i = 0;i<a.length;i++){ zmax += a[
基礎演算法--B最大欄位和
Description Given a sequencea[1],a[2],a[3]......a[n], your job is to calculate the max sum of asub-sequence. For example, given (6,-1,5,4
蠻力、分治、動態規劃求解最大欄位和問題(aardio)
最近的演算法課上要求做的一個實驗是分別用蠻力、分治、動態規劃求解最大欄位和問題。 以下是相關程式碼: 陣列求和程式段: var getsum = function(tab,frist,l
演算法設計與分析課作業【week3】leetode--105. Construct Binary Tree from Preorder and Inorder Traversal
題目 Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the t
演算法設計與分析課作業【week6】leetcode--8. String to Integer (atoi)
題目 Implement atoi which converts a string to an integer. The function first discards as many whitespace characters as necessary until th
演算法設計與分析課作業【week7】leetcode--151. Reverse Words in a String
題目 Given an input string, reverse the string word by word. Example: Input: "the sky is blue", Output: "blue is sky the". Note: A wo