演算法分析初步
8.1.1 漸進時間複雜度 ——最大連續和,給出乙個序列,找到i,j使連續和盡量大
使用列舉思想:列舉每乙個可能的序列首和序列尾
for( i = 1; i <= n; i++)
if( sum > best) best = sum;
}}
8.1.2 上界分析 ——三重迴圈,最壞情況下內層迴圈需要n次,故t(n) = o(n的3次方)(上界)
對這個程式進行簡化:連續子串行之和等於兩個字首和之差
for( i = 1; i <= n; i++)
}
8.1.3 分治法 ——分治法一般分為3個步驟
1、劃分問題:劃分成子問題 ; 把序列分成個數相等的兩半
2、遞迴問題:遞迴解決子問題; 分別求出完全位於左半或者右半的最佳序列
3、合併問題:合併子問題的解 求出起點位於左半終點位於右半的序列,並和子問題最優解比較
遞迴方程 t(n) = 2t(n/2) + o(n); t(1) = 1; 的解是t(n) = o(n log n)
再談排序和搜尋
8.2.1 歸併排序 ——也可以用分治法分成三個步驟
1、劃分問題:劃分成子問題 ; 把序列分成個數相等的兩半
2、遞迴問題:遞迴解決子問題; 兩半分別排序
3、合併問題:合併子問題的解 把兩個有序表合併成乙個
#includevoid sort( int* a, int x, int y, int* t);
int a = ;
int t[100];
int main(void)
void sort( int* a, int x, int y, int* t)
else
} for( i = x; i < y; i++)
} }
逆序對數(尚沒有仔細看懂)
8.2.2 快速排序 ——暫時略
8.2.3 二分查詢 ——折半查詢的思想,不過只針對有序序列
#includevoid sort( int* a, int x, int y, int* t); // 利用之前的分治方法進行排序
int main();
int t[100];
int x, y, m, v, i, num;
scanf("%d", &m);
sort( a, 0, 9, t);
for( i = 0; i < 9; i++) printf("%d ", a[i]);
printf("\n");
x = 0; y = 8;
num = 0;
while( x < y)
else if( a[v] <= m) x = v;
else y = v;
} return 0;
}void sort( int* a, int x, int y, int* t)
for( i = x; i < y; i++) a[i] = t[i];
}}
如果序列中有重複,且重複的為所求數字,那麼用原來的二分法就只能求得最中間的位置,需要進行一些小的修改
while( x < y)
else y = v; // 若求下界則是當相等時改變y
}
範圍統計:給出乙個序列,以及m個詢問,對於每個詢問(a, b),求閉區間 [a,b] 內個數
即求 a 所在的下界 l 和 b 所在的上界 r ,而後求區間 [ l, r]長度
遞迴與分治 ——【tbc】
貪心法 ——排序、取當前最優解
8.4.1 最優裝載問題 ——裝輕的比裝重的划算,故將所有物體按重量從小到大排列
8.4.2 部分揹包問題 ——部分選取,一定能讓總重量恰好為c。
8.4.3 乘船問題 ——兩個下表
i,j來表示當前最重和最輕的人
if(最輕的人
+最重的人
<
標準重) //
浪費最少
else //此時最重的只能自己乘一條船,往下尋找能和最輕的人同乘的 最重的人
8.4.4 選擇不相交區間 —— 有
n個區間
(ai, bi)
。如果區間
a能夠完全覆蓋
b則選取
a就是 不划算的,依據
bi將所有區間排序,那麼第乙個元素一定是在最優解中
排序後b1 < b2
①a1 >= a2
時,區間
1被區間
2完全包含,所以選取區間
2是不划算的
②a1 < a2
時,區間
1中位於
a2左邊的部分對結果並沒有影響,真正有影響 的是區間1 中
a2到b1部分,這一部分被區間
2完全包含,所以選取區間
2是不划算的
所以應該選取第乙個區間,然後需尋找此後與此區間不相交的第乙個區間
8.4.5 區間選點問題 ——小區間被滿足時大區間也會被滿足,所以在區間包含的情況下大區 間不用考慮。依據
bi將所有區間排序,然後取最後乙個點
[s,t]
外的部分都切掉,因為存在 無意義。依據
ai將所有區間排序,如果第乙個區間起點不是
s,則無解。否則選取最長區間,隨後設定此區間尾
bi為新的起點。
8.4.7 huffman編碼 ——證明用
huffman
樹可以得出最優解需要以下兩個結論:
①如果編碼a
是編碼b
的字首,那麼
a對應的結點一定為
b所對應結點的祖先。 而兩個葉結點不存在祖先後代的關係
②最有字首碼一定可以寫成二叉樹
構造一顆最優編碼樹(huffman演算法)
:每棵子樹權值等於相應字元的頻率,每次 選擇權值最小的樹組成一顆權值為兩樹之和的新樹,放回集合中。滿足以下兩個性質
①設x,y
是使用頻率最小的兩個字元,存在字首碼使二者具有相同碼長,僅有 最後一位不同
(保留了最優解)
②設z為
x,y的父結點,把
z看成頻率具有
x,y頻率之和的字元,那麼此樹是 包含z而無
x,y字元的集合的最優解
(最優子結構性質
)
第8周讀書筆記
構建之法 讀書筆記 part1 開學了這麼久還沒有自覺的看過課本,讀課本都是在老師布置任務的時候有需要再看的。這週就自己主動的看了一點這本書。翻開這本書就帶來了不小的視覺衝擊。軟體 程式 演算法的概念深入我心,但是書上把 演算法 改成了 軟體工程 開發乙個軟體的過程是多方面的,源程式 資料 軟體架構...
第1 2 16章讀書筆記
第一章 概論 原文 乙個好的軟體,即使功能和同類軟體區別不大,但卻會讓人感覺到非常好用。這就是軟體的使用者體驗。使用者體驗和資料結構,演算法沒有直接的關係,但是很多非常成功的軟體就贏在這個方面。軟體還要處理 不同語言,不同地區的使用者對介面和功能的不同需求,這個叫做軟體的國際化和本地化。1.使用者體...
《HeadFirst設計模式》讀書筆記 第7章
定義 外觀模式 facade pattern 提供了乙個統一的介面,用來訪問子系統中的一群介面。外觀定義了乙個高層介面,讓子系統更加容易使用。從上面的圖可以看出,facade類對子系統進行了一下封裝,客戶只需要和facade類打交道,不需要接觸子系統中的各個類,也不需要了解子系統中各個類間的關係。從...