一,概述
問題:求一維陣列中連續子向量的最大和。
例如:a[6]=; 則最大連續子向量的和 為 10+8 = 18
1)解法一:簡單演算法
#include #define max(a, b) ((a)>(b)?(a):(b))
int main()
; int i,j,k;
int sum=0;
int maxsofar=0;
for(i=0;i<6;++i)
maxsofar=max(maxsofar,sum);
} }printf("max=%d\n",maxsofar);
return 0;
}
2)兩個平方演算法
演算法一:
#include #define max(a, b) ((a)>(b)?(a):(b))
int main()
; int i,j;
int sum=0;
int maxsofar=0;
for(i=0;i<6;++i) }
printf("max=%d\n",maxsofar);
return 0;
}
演算法二:
#include #define max(a, b) ((a)>(b)?(a):(b))
int main()
; int cumarr[6]; cumarr[-1]=0;
int i,j;
int sum=0;
int maxsofar=0;
for(i=0;i<6;++i)
for(i=0;i<6;++i) }
printf("max=%d\n",maxsofar);
return 0;
}
3)分治演算法
思想:以m為分界線,最大值有三種情況
一:在m左側
二:在m右側
三:跨越m
關鍵:最初求解左右最大值時候,一定要從中間向兩側遞增。看原始碼解釋……
#include "stdio.h"
#define max(a,b) a>b?a:b
int a[6]=;
int max2(int a,int b,int c)
int maxsum(int l,int u)
printf("m=:%d\n",m);
rmax =sum =0;
for(i=m+1;i<=u;++i)
return max2(lmax + rmax , maxsum(l,m) , maxsum(m+1,u) );
}int main()
【注意】 max2() 如果用巨集 #define max(a,b,c) max(a,b) >c?max(a,b):c 則不會得到正確結果
4)掃瞄演算法
#include "stdio.h"
int main()
; int i,sum=0;
for(i=0;i<6;++i)
printf("max=%d",sum);
return 0;
}
二,總結
優化演算法的策略
1)儲存已經計算的狀態,避免重複計算。
2)將資訊預處理到資料結構中。例如演算法二
3)分治演算法,採取更高階的演算法
4)掃瞄演算法,巧妙
5)下界:證明某個匹配的下界,確定最優演算法
三,習題
10)可以採用兩種方法:o(n*n)
#include #define min(a, b) ((a)>(b)?(b):(a))
#define obs(a) a>0?a:-a
int main()
; int i,j,k;
int sum=0;
int maxsofar=65535;//這個很關鍵
for(i=0;i<6;++i)
maxsofar=min(maxsofar,obs(sum));
} }printf("max=%d\n",maxsofar);
return 0;
}
返回結果是 1
可以採用o(nlogn)的演算法
#include #define min(a, b) ((a)>(b)?(b):(a))
#define obs(a) a>0?a:-a
/*先將 軸 記錄在temp 中 先從後面向前找小於軸的 放到第乙個(即軸所在位置)
再從前向後找 大於軸的元素 存放到 上一步找到的小於軸的位置
總之:要做的是將後面小於軸的 跟 前面大於軸的 做替換 】
當退出while 迴圈後 因為最後收場的是 i從低端加上來 所以 i 的位置對應 軸最後要存放的位置*/
int partition(int a,int i,int j)
a[i]=temp;//軸的位置
return i;
}void quicksort(int a,int i,int j)
{ int p;
if(i
返回結果是 1
13)最大子陣列問題,給定n*n陣列,求矩形子陣列的最大總和。
詳見部落格:
程式設計珠璣第八章 演算法設計技術
本章就乙個小問題研究了四種不同的演算法,重點強調了這些演算法的設計技術,綜合本章內容,告訴我們 複雜深奧的演算法有時可以極大地提高程式效能。問題定義 具有n個浮點數的向量x,求出輸入向量的任何連續子向量的最大和。立方演算法 maxsofar 0 for i 0,n for j i,n sum 0 f...
程式設計珠璣第八章 演算法設計技術
首先思考乙個問題,給定乙個含有n個元素的vector,找出其中最大的子向量 即所有元素之和為最大值 如果是都為正數,那麼問題變得十分簡單,整個vector即是最大子向量,但是如果是正數負數混合的形式呢?問題將變得複雜,接下來將簡要介紹幾種演算法的思路。其複雜度由最初的立方演算法降低到最終的線性演算法...
《程式設計珠璣》學習記錄第八章演算法設計技術
演算法的設計這個問題太過龐大,對於乙個程式設計師來說,最好的辦法就是多接觸不同的演算法,並且時刻總結。問題 乙個一維的整數陣列,有n個元素,元素有正數也有負數。找到陣列中任意連續個元素最大和。方法一 使用暴力法找到所有的子串行,並計算出所有子串行的和,結果自然就得到了。這種方法的事件複雜度是o n ...