算法设计与分析——贪心法

贪心法的思想(听着容易,然是需要证明啊)

贪心选择性
优化子结构
后面老师还讲了拟阵,那块特别抽象,写着就没啥必要了。

课上例题

1.活动安排问题

输入: S = { 1 , 2 , … , n } , F = { [ s i , f i ] } , n ≥ i ≥ 1 S=\{1, 2, …, n\},F=\{ [s_i,f_i] \},n\ge i\ge 1 S={ 1,2,,n}F={ [sifi]}ni1
输出: S S S的最大相容集合

首先应该明白什么是相容的,用图片的方式就能很容易的表现出来。

Mon 06 Mon 13 [s_i,f_i] [s_j,f_j] [s_k,f_k]

上图中表示的就是相容的活动,也就是对于 ∀ 1 ≤ i , j ≤ n , s i ≥ f j 或 s j ≥ f i \forall 1\le i,j\le n,s_i\ge f_j或s_j\ge f_i 1i,jn,sifjsjfi,更直观一点就是两个活动的时间上不能有交集。我们这种题的贪心思想就是:为了选择最多的相容活动,每次选 f i f_i fi(或者 s i s_i si)最小的活动,使我们能够选更多的活动。下面就应该分别证明贪心选择性和优化子结构(一般就是使用反证法和归纳法):

S = { 1 , 2 , … , n } S=\{1,2,…,n\} S={ 1,2,,n} n n n个活动集合, [ s i , f i ] [s_i,f_i] [sifi]是活动的起始终止时间,且 f 1 ≤ f 2 ≤ … . ≤ f n , S f_1\le f_2\le ….\le f_n,S f1f2.fnS的活动选择问题的某个优化解包括活动 1 1 1.

证明:假设 A A A S S S的一个优化解, A A A的第一个活动的结束时间是 f k f_k fk,对 ∀ s j ∈ A \forall s_j\in A sjA,因为A是优化解,所以 A A A中的活动都是相容的,所以 f k ≤ s j f_k\le s_j fksj,因为 f 1 ≤ f 2 ≤ … . ≤ f n f_1\le f_2\le ….\le f_n f1f2.fn,所以 f 1 ≤ f k ≤ s j f_1\le f_k\le s_j f1fksj,所以 A ′ = A − [ s k , f k ] + [ s 1 , f 1 ] A'=A-[s_k,f_k]+[s_1,f_1] A=A[sk,fk]+[s1,f1]也一定是一个优化解,里面的元素都是互不相容的并且 ∣ A ∣ = ∣ A ′ ∣ |A|=|A'| A=A

S = { 1 , 2 , … , n } S=\{1, 2, …, n\} S={ 1,2,,n} n n n个活动集合, [ s i , f i ] [s_i,f_i] [sifi]是活动 i i i 的起始终止时间,且 f 1 ≤ f 2 ≤ … . ≤ f n f_1\le f_2\le ….\le f_n f1f2.fn,设 A A A S S S的调度问题的一个优化解且包括活动 1 1 1,则 A ′ = A − { 1 } A'=A-\{1\} A=A{ 1} S ′ = { i ∈ S ∣ s i ≤ f 1 } S'=\{i\in S|s_i\le f_1\} S={ iSsif1}的调度问题的优化解.

证明:由于 A A A是一个优化解,所以 A A A中的元素肯定是互不相容的,所以 A ′ = A − { 1 } A'=A-\{1\} A=A{ 1}里面的活动也一定都是互不相容的,所以我们只需要证明他是个最大的互不相容的活动的集合就好了。如果他不是最大的,有 B ′ B' B S ′ = { i ∈ S ∣ s i ≤ f 1 } S'=\{i\in S|s_i\le f_1\} S={ iSsif1}的调度问题的优化解。同时 ∣ B ′ ∣ > ∣ A ′ ∣ |B'|>|A'| B>A。所以,而 B ′ B' B中一定是不含活动1的,所以令 B = B ′ + { 1 } B=B'+\{1\} B=B+{ 1},所以 ∣ B ∣ > ∣ A ∣ |B|>|A| B>A,但是 A A A是一个优化解,所以矛盾。

S = 1 , 2 , … . , n S={1, 2, …., n} S=1,2,.,n n n n个活动集合, f 0 = 0 f_0=0 f0=0, l i l_i li S i = { j ∈ S ∣ s j ≥ f i − 1 } S_i =\{ j\in S | s_j\ge f_{i-1}\} Si={ jSsjfi1} 中具有最小结束时间 f l i f_{l_i} fli的活动.设 A A A S S S的包含活动 1 1 1的优化解, 其中 f 1 ≤ … ≤ f n f1\le …\le fn f1fn,则 A = ∪ i = 1 k l i A=\cup_{i=1}^{k}l_i A=i=1kli

证明: ∣ A ∣ = 1 |A|=1 A=1的时候, A A A中显然包含 l 1 l_1 l1;假设 ∣ A ∣ < k |A|A<k的时候成立,往证 ∣ A ∣ = k |A|=k A=k的时候成立, A = A ′ + { 1 } A=A'+\{1\} A=A+{ 1} A ′ A' A S ′ = { i ∈ S ∣ s i ≤ f 1 } S'=\{i\in S|s_i\le f_1\} S={ iSsif1}的优化解,加上 { 1 } \{1\} { 1}就是 S S S的优化解了。

(设 f 1 ≤ f 2 ≤ … . ≤ f n f1\le f2\le….\le fn f1f2.fn已排序)
G r e e d y − A c t i v i t y − S e l e c t o r ( S , F ) ( 1 ) n ← l e n g t h ( S ) ; ( 2 ) A ← 1 ( 3 ) j ← 1 ( 4 ) F o r i ← 2 T o n D o ( 5 ) I f s i ≥ f j ( 6 ) T h e n A ← A ∪ i ; j ← i ; ( 7 ) R e t u r n Greedy-Activity-Selector(S, F) \\ (1)n\leftarrow length(S);\\ (2)A\leftarrow {1}\\ (3)j\leftarrow 1\\ (4)For\quad i\leftarrow 2\quad To\quad n\quad Do\\ (5)\quad If si\ge fj\\ (6)\quad Then\quad A\leftarrow A∪{i};j\leftarrow i;\\ (7)Return GreedyActivitySelector(S,F)(1)nlength(S);(2)A1(3)j1(4)Fori2TonDo(5)Ifsifj(6)ThenAAiji(7)Return
时间复杂度: T ( n ) = Θ ( n l o g n ) T(n)=\Theta(nlogn) T(n)=Θ(nlogn)

2.哈夫曼编码问题

输入: 字母表 C = { c 1 , c 2 , . . . . , c n } C=\{c1, c2, ...., cn\} C={ c1,c2,....,cn}频率表 F = { f ( c 1 ) , f ( c 2 ) , . . . , f ( c n ) } F=\{f(c1), f(c2), ..., f(cn)\} F={ f(c1),f(c2),...,f(cn)}
输出: 具有最小 B ( T ) B(T) B(T) C C C前缀编码树( B ( T ) = ∑ c ∈ C f ( c ) d ( c ) B(T)= \sum_{c\in C}f(c)d(c) B(T)=cCf(c)d(c)

C C C是字母表, c ∈ C c\in C cC c c c具有频率 f ( c ) f(c) f(c), x x x y y y C C C中具有最小频率的两个字符,则存在一个 C C C的优化前缀树, x x x y y y的编码具有相同长度,且仅在最末一位不同.

证明:假设 b , c b,c b,c是两个深度最大的叶子结点,因为 x x x y y y C C C中具有最小频率的两个字符,所以 f ( b ) ≥ f ( x ) , f ( c ) ≥ f ( y ) f(b)\ge f(x),f(c)\ge f(y) f(b)f(x),f(c)f(y),所以将 x x x b b b互换位置, y y y c c c互换位置,得到 T ′ T' T,那么 B ( T ) − B ( T ′ ) = f ( x ) d ( x ) + f ( y ) d ( y ) + f ( b ) d ( b ) + f ( c ) d ( c ) − f ( x ) d ( b ) − f ( y ) d ( c ) − f ( b ) d ( x ) − f ( c ) d ( y ) = ( f ( x ) − f ( b ) ) ( d ( x ) − d ( b ) ) + ( f ( y ) − f ( c ) ) ( d ( y ) − d ( c ) ) ≥ 0 B(T)-B(T')=f(x)d(x)+f(y)d(y)+f(b)d(b)+f(c)d(c)-f(x)d(b)-f(y)d(c)-f(b)d(x)-f(c)d(y)=(f(x)-f(b))(d(x)-d(b))+(f(y)-f(c))(d(y)-d(c))\ge 0 B(T)B(T)=f(x)d(x)+f(y)d(y)+f(b)d(b)+f(c)d(c)f(x)d(b)f(y)d(c)f(b)d(x)f(c)d(y)=(f(x)f(b))(d(x)d(b))+(f(y)f(c))(d(y)d(c))0,所以换完了之后获得了一个代价更小的树。

T T T是字母表 C C C的优化前缀树, c ∈ C c\in C cC f ( c ) f(c) f(c) c c c在文件中出现的频率.设 x x x y y y T T T中任意两个相邻叶结点, z z z是它们的父结点,则 z z z作为频率是 f ( z ) = f ( x ) + f ( y ) f(z)=f(x)+f(y) f(z)=f(x)+f(y)的字符, T ’ = T − { x , y } T’=T-\{x,y\} T=T{ x,y}是字母表 C ’ = C − { x , y } ∪ { z } C’=C-\{x,y\}∪\{z\} C=C{ x,y}{ z}的优化前缀编码树.

证明:首先 B ( T ) = B ( T ′ ) + f ( x ) + f ( y ) B(T)=B(T')+f(x)+f(y) B(T)=B(T)+f(x)+f(y)这个是很好证明的,对于 ∀ k ∈ C , k ≠ x & & k ≠ y , f ( k ) = f ′ ( k ) , d ( k ) = d ′ ( k ) \forall k\in C,k\ne x\&\&k\ne y,f(k)=f'(k),d(k)=d'(k) kC,k=x&&k=y,f(k)=f(k),d(k)=d(k),所以对于其他的节点没有任何影响,对于 x , y , d ( x ) = d ( y ) = d ′ ( z ) + 1 , f ′ ( z ) = f ( x ) + f ( y ) x,y,d(x)=d(y)=d'(z)+1,f'(z)=f(x)+f(y) x,yd(x)=d(y)=d(z)+1,f(z)=f(x)+f(y),所以, B ( T ′ ) = ∑ d ′ ( k ) f ′ ( k ) + d ′ ( z ) f ′ ( z ) = ∑ d ( k ) f ( k ) + ( d ( x ) − 1 ) ( f ( x ) + f ( y ) ) = B ( T ) − f ( x ) − f ( y ) B(T')=\sum d'(k)f'(k)+d'(z)f'(z)=\sum d(k)f(k)+(d(x)-1)(f(x)+f(y))=B(T)-f(x)-f(y) B(T)=d(k)f(k)+d(z)f(z)=d(k)f(k)+(d(x)1)(f(x)+f(y))=B(T)f(x)f(y),现在证明 T ′ T' T是最优的子树,如果不是则存在 T ′ ′ T'' T使得 B ( T ′ ′ ) < B ( T ) B(T'')B(T)<B(T),将 x , y x,y x,y放回 T ′ ′ T'' T中, B ( T ′ ′ ′ ) = B ( T ′ ′ ) + f ( x ) + f ( y ) < B ( T ) B(T''')=B(T'')+f(x)+f(y)B(T)=B(T)+f(x)+f(y)<B(T),矛盾,所以 T ′ T' T是最优的子树。

H u f f m a n ( C , F ) ( 1 ) n ← C ; ( 2 ) Q ← C ; ( 3 ) F O R i ← 1 T o n − 1 D o ( 4 ) z ← A l l o c a t e − N o d e ( ) ; ( 5 ) x ← l e f t [ z ] ← E x t r a c t − M I N ( Q ) ; ( 6 ) y ← r i g h t [ z ] ← E x t r a c t − M I N ( Q ) ; ( 7 ) f ( z ) ← f ( x ) + f ( y ) ; ( 8 ) I n s e r t ( Q , z ) ; ( 9 ) R e t u r n Huffman(C,F)\\ (1)n\leftarrow C;\\ (2)Q\leftarrow C;\\ (3)FOR\quad i\leftarrow 1\quad To\quad n-1\quad Do\\ (4)\quad z\leftarrow Allocate-Node( );\\ (5)\quad x\leftarrow left[z]\leftarrow Extract-MIN(Q);\\ (6)\quad y\leftarrow right[z]\leftarrow Extract-MIN(Q);\\ (7)\quad f(z)\leftarrow f(x)+f(y);\\ (8)\quad Insert(Q, z); \\ (9)Return Huffman(CF)(1)nC;(2)QC;(3)FORi1Ton1Do(4)zAllocateNode();(5)xleft[z]ExtractMIN(Q);(6)yright[z]ExtractMIN(Q);(7)f(z)f(x)+f(y);(8)Insert(Q,z);(9)Return
时间复杂度: T ( n ) = O ( n l o g n ) T(n)=O(nlogn) T(n)=O(nlogn)

3.最小生成子树

输入: 无向连通图 G = ( V , E ) G=(V, E) G=(V,E), 权函数 W W W
输出: G G G的最小生成树
这个主要就是 k r u s k a l kruskal kruskal p r i m prim prim算法

u v uv uv G G G中权值最小的边,则必有一棵最小生成树包含边 u v uv uv.

证明:如果最小生成树 T T T中不包含边 u v uv uv,那么找到 T T T中的最小边 u ′ v ′ u'v' uv,令 T ′ = T − { u v } + { u ′ v ′ } T'=T-\{uv\}+\{u'v'\} T=T{ uv}+{ uv},我们能够发现 T ′ T' T中包含了所有的顶点,而且是一棵树,并且 W ( T ′ ) ≤ W ( T ) W(T')\le W(T) W(T)W(T),跟 T T T是最小生成树矛盾,所以一定包含最短边 u v uv uv

给定加权无向连通图 G = ( V , E ) G=(V,E) G=(V,E),权值函数为 W : E → R W:E\rightarrow R W:ER, u v ∈ E uv\in E uvE G G G中权值最小的边。设 T T T G G G的包含 u v uv uv的一棵最小生成树,则 T ⋅ u v T\cdot uv Tuv G ⋅ u v G\cdot uv Guv的一棵最小生成树.

证明:我们发现 T ⋅ u v T\cdot uv Tuv肯定包含了 G ⋅ u v G\cdot uv Guv中的所有顶点,所以 T ⋅ u v T\cdot uv Tuv肯定是棵树,现在证明他是最小的。假设他不是最小生成树,存在 T ′ T' T G ⋅ u v G\cdot uv Guv的最小生成树, T ′ T' T中肯定包含 C u v C_{uv} Cuv这个点,将边 u v uv uv加到 G ⋅ u v G\cdot uv Guv中,则 W ( T ′ ) + W ( u v ) < W ( T ⋅ u v ) + W ( u v ) = W ( T ) W(T')+W(uv)W(T)+W(uv)<W(Tuv)+W(uv)=W(T),与 T T T G G G的最小生成树矛盾。

M S T − K r u s k a l ( G , W ) ( 1 ) A = ∅ ; ( 2 ) F o r ∀ v ∈ V [ G ] D o ( 3 ) M a k e − S e t ( v ) ; ( 4 ) 按 照 W 值 的 递 增 顺 序 排 序 E [ G ] ; ( 5 ) F o r ∀ ( u , v ) ∈ E [ G ] ( 按 W 值 的 递 增 顺 序 ) D o ( 6 ) I f F i n d − S e t ( u ) ≠ F i n d − S e t ( v ) ( 7 ) T h e n A = A ∪ ( u , v ) ; U n i o n ( u , v ) ; ( 8 ) R e t u r n MST-Kruskal(G,W)\\ (1)A=\emptyset;\\ (2)For\forall v\in V[G] Do\\ (3)\quad Make-Set(v); \\ (4)按照W值的递增顺序排序E[G];\\ (5)For\forall (u, v)\in E[G] (按W值的递增顺序) Do\\ (6)\quad If Find-Set(u)\ne Find-Set(v)\\ (7)\quad Then A=A\cup{(u, v)}; Union(u, v);\\ (8)Return MSTKruskal(G,W)(1)A=;(2)ForvV[G]Do(3)MakeSet(v);(4)WE[G];(5)For(u,v)E[G](W)Do(6)IfFindSet(u)=FindSet(v)(7)ThenA=A(u,v);Union(u,v);(8)Return
时间复杂度是: T ( n ) = O ( m l o g m ) , m = ∣ E ∣ T(n)=O(mlogm),m=|E| T(n)=O(mlogm),m=E

M S T − P r i m ( G , W , r ) ( 1 ) F o r ∀ v ∈ V [ G ] D o ( 2 ) k e y [ v ] ← + ∞ ( 3 ) [ v ] ← n u l l ( 4 ) k e y [ r ] ← 0 ( 5 ) Q ← V [ G ] ( 6 ) W h i l e Q ≠ ∅ d o ( 7 ) u ← E x t r a c t _ M i n ( Q ) ( 8 ) f o r ∀ v ∈ A d j [ u ] d o ( 9 ) i f v ∈ Q 且 w ( u , v ) < k e y [ v ] t h e n ( 10 ) π [ v ] ← u ( 11 ) k e y [ v ] ← w ( u , v ) ( 12 ) R e t u r n A = { ( v , π [ v ] ) ∣ v ∈ V [ G ] − r } MST-Prim(G,W,r)\\ (1)For\quad\forall v\in V[G]\quad Do\\ (2)\quad key[v]\leftarrow+\infin\\ (3)\quad [v]\leftarrow null\\ (4)key[r]\leftarrow 0\\ (5)Q\leftarrow V[G]\\ (6)While\quad Q\ne\emptyset\quad do\\ (7)\quad u\leftarrow Extract\_Min(Q)\\ (8)\quad for\quad\forall v\in Adj[u]\quad do\\ (9)\quad if v\in Q 且 w(u,v)MSTPrim(G,W,r)(1)ForvV[G]Do(2)key[v]+(3)[v]null(4)key[r]0(5)QV[G](6)WhileQ=do(7)uExtract_Min(Q)(8)forvAdj[u]do(9)ifvQw(u,v)<key[v]then(10)π[v]u(11)key[v]w(u,v)(12)ReturnA={ (v,π[v])vV[G]r}
时间复杂度是: T ( n ) = O ( E l o g V ) T(n)=O(ElogV) T(n)=O(ElogV)

课后习题

1.现有一台计算机, 在某个时刻同时到达了 n n n个任务。该计算机在同一时间只能处理一个任务, 每个任务都必须被不间断地得到处理。该计算机处理这 n n n个任务需要的时间分别为 a 1 , a 2 , . . . , a n a_1 ,a_2 ,...,a_n a1,a2,...,an。将第 i i i 个任务在调度策略中的结束时间记为 e i e_i ei。请设计一个贪心算法输出这 n n n 个任务的一个调度使得用户的平均等待时间 1 / n ∑ e i 1/n∑e_i 1/nei达到最小。

解:贪心算法:每次都选择消耗时间少的
贪心选择性:即有一个最优解优先执行任务1,假设任务1是执行时间最少的。任务 j j j的结束时间就是 ∑ i = 1 j a i \sum_{i=1}^{j}a_i i=1jai那么平均等待时间就是$1/n∑e_i= 1 / n ∑ j = 1 n ∑ i = 1 j a i 1/n\sum_{j=1}^{n}\sum_{i=1}^{j}a_i 1/nj=1ni=1jai,假设有一个最优解 i 1 , i 2 , . . . , i n i_1,i_2,...,i_n i1,i2,...,in,若 i 1 i_1 i1是任务1,那么就有一个最优解优先执行任务1了。若 i t i_t it是任务1,那么交换 i 1 i_1 i1 i t i_t it,新的等待时间 T ′ = n i t + ( n − 1 ) i 2 + . . . + ( n − t + 1 ) i 1 + . . . + i n T'=ni_t+(n-1)i_2+...+(n-t+1)i_1+...+i_n T=nit+(n1)i2+...+(nt+1)i1+...+in T = n i 1 + ( n − 1 ) i 2 + . . . + ( n − t + 1 ) i t + . . . + i n T=ni_1+(n-1)i_2+...+(n-t+1)i_t+...+i_n T=ni1+(n1)i2+...+(nt+1)it+...+in T ′ − T = n ( i t − i 1 ) + ( n − t + 1 ) ( i 1 − i t ) = ( t − 1 ) ( i t − i 1 ) ≤ 0 T'-T=n(i_t-i_1)+(n-t+1)(i_1-i_t)=(t-1)(i_t-i_1)\le 0 TT=n(iti1)+(nt+1)(i1it)=(t1)(iti1)0 T T T是优化解,所以 T = T ′ T=T' T=T,所以先执行任务1,也是一个优化解

优化子结构:有一个 i 1 , i 2 , . . . , i n i_1,i_2,...,i_n i1,i2,...,in n n n个任务的优化解,则 i 2 , . . . , i n i_2,...,i_n i2,...,in n − 1 n-1 n1个任务的优化解。不然,则存在一组解 j 2 , . . . , j n j_2,...,j_n j2,...,jn,其等待时间 T ′ ′ ′ < T ′ ′ T'''T<T,所以 i 1 , j 2 , . . . , j n i_1,j_2,...,j_n i1,j2,...,jn n n n个问题的优化解,这就与 i 1 , i 2 , . . . , i n i_1,i_2,...,i_n i1,i2,...,in n n n个任务的优化解矛盾。

2.现有面值为 1 角、5 分、2 分、1 分的硬币, 每种硬币的个数都是无限的。给出一个贪心算法, 使得对任意给定的面值为 n ( n > 18 ) n(n > 18) n(n>18) 分的纸币能够将它兑换成币值相等的硬币且使用硬币个数最少。证明算法的正确性并分析其复杂度。

解:贪心算法:每次选择面值尽可能大的硬币
贪心选择性:当 n ≥ 10 n\ge 10 n10时,选择1角硬币,若不然,则需要选2个5分或 5个2分或10个1分硬币;当 5 ≤ n < 10 5\le n<10 5n<10时,选择5分,若不然,则需要选择5个1分或2个2分1个1分或1个2分3个1分;当 2 ≤ n < 5 2\le n<5 2n<5时,选择2分,若不然,则需要选择2个1分。显然按面值选好。
优化子结构:显然有优化子结构。

3.给定 k k k 个排好序的有序序列 s 1 , s 2 , . . . , s k s_1 ,s_2 ,...,s_k s1,s2,...,sk ,现在用 2 路归并排序算法对这些有序序列排序。假定用 2 路归并排序算法对长度分别为 m m m n n n 的有序序列排序要用 m + n − 1 m+n−1 m+n1 次比较操作。设计一个贪心算法合并 s 1 , s 2 , . . . , s k s_1 ,s_2 ,...,s_k s1,s2,...,sk 使得所需的比较操作次数最少。

解:贪心算法:选择 s i l e n g t h s_i{length} silength最小的两个进行合并。
贪心选择性:假设 b , c b,c b,c是两个深度最大的叶子结点,因为 x x x y y y S S S中具有长度最小的两个序列,所以 f ( b ) ≥ f ( x ) , f ( c ) ≥ f ( y ) f(b)\ge f(x),f(c)\ge f(y) f(b)f(x),f(c)f(y),所以将 x x x b b b互换位置, y y y c c c互换位置,得到 T ′ T' T,那么 B ( T ) − B ( T ′ ) = f ( x ) d ( x ) + f ( y ) d ( y ) + f ( b ) d ( b ) + f ( c ) d ( c ) − f ( x ) d ( b ) − f ( y ) d ( c ) − f ( b ) d ( x ) − f ( c ) d ( y ) = ( f ( x ) − f ( b ) ) ( d ( x ) − d ( b ) ) + ( f ( y ) − f ( c ) ) ( d ( y ) − d ( c ) ) ≥ 0 B(T)-B(T')=f(x)d(x)+f(y)d(y)+f(b)d(b)+f(c)d(c)-f(x)d(b)-f(y)d(c)-f(b)d(x)-f(c)d(y)=(f(x)-f(b))(d(x)-d(b))+(f(y)-f(c))(d(y)-d(c))\ge 0 B(T)B(T)=f(x)d(x)+f(y)d(y)+f(b)d(b)+f(c)d(c)f(x)d(b)f(y)d(c)f(b)d(x)f(c)d(y)=(f(x)f(b))(d(x)d(b))+(f(y)f(c))(d(y)d(c))0,所以换完了之后获得了一个代价更小的树。
优化子结构:首先 B ( T ) = B ( T ′ ) + f ( x ) + f ( y ) B(T)=B(T')+f(x)+f(y) B(T)=B(T)+f(x)+f(y)这个是很好证明的,对于 ∀ k ∈ C , k ≠ x & & k ≠ y , f ( k ) = f ′ ( k ) , d ( k ) = d ′ ( k ) \forall k\in C,k\ne x\&\&k\ne y,f(k)=f'(k),d(k)=d'(k) kC,k=x&&k=y,f(k)=f(k),d(k)=d(k),所以对于其他的节点没有任何影响,对于 x , y , d ( x ) = d ( y ) = d ′ ( z ) + 1 , f ′ ( z ) = f ( x ) + f ( y ) x,y,d(x)=d(y)=d'(z)+1,f'(z)=f(x)+f(y) x,yd(x)=d(y)=d(z)+1,f(z)=f(x)+f(y),所以, B ( T ′ ) = ∑ d ′ ( k ) f ′ ( k ) + d ′ ( z ) f ′ ( z ) = ∑ d ( k ) f ( k ) + ( d ( x ) − 1 ) ( f ( x ) + f ( y ) ) = B ( T ) − f ( x ) − f ( y ) B(T')=\sum d'(k)f'(k)+d'(z)f'(z)=\sum d(k)f(k)+(d(x)-1)(f(x)+f(y))=B(T)-f(x)-f(y) B(T)=d(k)f(k)+d(z)f(z)=d(k)f(k)+(d(x)1)(f(x)+f(y))=B(T)f(x)f(y),现在证明 T ′ T' T是最优的子树,如果不是则存在 T ′ ′ T'' T使得 B ( T ′ ′ ) < B ( T ) B(T'')B(T)<B(T),将 x , y x,y x,y放回 T ′ ′ T'' T中, B ( T ′ ′ ′ ) = B ( T ′ ′ ) + f ( x ) + f ( y ) < B ( T ) B(T''')=B(T'')+f(x)+f(y)B(T)=B(T)+f(x)+f(y)<B(T),矛盾,所以 T ′ T' T是最优的子树。

4.给定两个大小为 n n n 的正整数集合 A A A B B B。对于 A A A B B B 的一个一一映射 f f f, 不妨设 f ( a i ) = b i ( i = 1 , . . . , n ) f(a_i ) = b_i (i = 1,...,n) f(ai)=bi(i=1,...,n), 则 f f f 的代价为 ∑ n i = a i b i ∑n_i= a_i^{b_i} ni=aibi。试设计一个贪心算法, 找出从 A A A B B B 的代价最大的一一映射。

解:贪心算法:每次选择 A A A B B B中最大的两个数
贪心选择性:将 A A A B B B排序,之后等到递减序列 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an b 1 , b 2 , . . . , b n b_1,b_2,...,b_n b1,b2,...,bn,若 f ( a 1 ) = b i f(a_1) = b_i f(a1)=bi f ( a j ) = b 1 f(a_j) = b_1 f(aj)=b1,交换两个使得 f ( a 1 ) = b 1 f(a_1) = b_1 f(a1)=b1 f ( a j ) = b i f(a_j) = b_i f(aj)=bi,得到差 δ = a 1 b 1 + a j b i − a 1 b i − a j b 1 = a 1 b i ( a 1 b 1 − b i − 1 ) − a j b i ( a j b 1 − b i − 1 ) ≥ 0 \delta=a_1^{b_1}+a_j^{b_i}-a_1^{b_i}-a_j^{b_1}=a_1^{b_i}(a_1^{b_1-b_i}-1)-a_j^{b_i}(a_j^{b_1-b_i}-1)\ge0 δ=a1b1+ajbia1biajb1=a1bi(a1b1bi1)ajbi(ajb1bi1)0所以,选最大的两个数更好
优化子结构: f ′ : A − a 1 → B − b 1 f':A-a_1\rightarrow B-b_1 f:Aa1Bb1,排序后 f ( a i ) = b i ( i = 2 , . . . , n ) f(a_i ) = b_i (i = 2,...,n) f(ai)=bi(i=2,...,n),若不然,则存在一个映射 f ′ ′ f'' f使得代价更大,加上 f ( a 1 ) = b 1 f(a_1) = b_1 f(a1)=b1这个条件,就与 f f f是优化解矛盾。

5.一个 D N A DNA DNA 序列 X X X 是字符集 G , T , A , C G,T,A,C G,T,A,C 上的串, 其上有大量信息冗余。设 x x x X X X 的子串, x x x 及其冗余形式在 X X X 内在出现的起、止位置构成了一系列等长区间 [ p 1 , q 1 ] , . . . , [ p m , q m ] [p_1,q_1],...,[p_m ,q_m] [p1,q1],...,[pm,qm]。试设计一个贪心算法找出 [ p 1 , q 1 ] , . . . , [ p m , q m ] [p_1,q_1],...,[p_m ,q_m ] [p1,q1],...,[pm,qm]中互不相交的区间的最大个数, 即确定 x x x 的独立冗余度。

解:贪心算法:每次选 q i q_i qi最小的区间(选 p i p_i pi最大的区间也一样)
贪心选择性:将区间按照 q i q_i qi排序得到 [ p 1 , q 1 ] , . . . , [ p m , q m ] [p_1,q_1],...,[p_m ,q_m] [p1,q1],...,[pm,qm],证明存在优化解包含 [ p 1 , q 1 ] [p_1,q_1] [p1,q1],设有优化解 S S S,第一个元素是 [ p i , q i ] [p_i,q_i] [pi,qi],若 i = 1 i=1 i=1,那么结论成立,否则 S ’ = S − { i } + { 1 } S’=S-\{i\}+\{1\} S=S{ i}+{ 1},对于任意元素 q 1 < q j q_1q1<qj,因为优化解 S S S第一个元素是 [ p i , q i ] [p_i,q_i] [pi,qi],所以 q i < p j q_iqi<pj,所以 q 1 < p j q_1q1<pj,所以 S ′ = S − { i } + { 1 } S'=S-\{i\}+\{1\} S=S{ i}+{ 1}还是优化解。
优化子结构: S S S是包含 { 1 } \{1\} { 1}的优化解,证明 S ′ = S − { 1 } S'=S-\{1\} S=S{ 1}是最大的。若不然,存在 S ′ ′ S'' S使得 ∣ S ′ ′ ∣ > ∣ S ′ ∣ |S''|>|S'| S>S,其中 ∣ S ′ ∣ |S'| S ∣ S ′ ′ ∣ |S''| S的区间互不相交。加上 { 1 } \{1\} { 1} ∣ S ′ ′ + { 1 } ∣ > ∣ S ′ + { 1 } ∣ = ∣ S ∣ |S''+\{1\}|>|S'+\{1\}|=|S| S+{ 1}>S+{ 1}=S,矛盾。

6.某工厂收到 n n n 个订单 ( a i , b i ) (a_i ,b_i ) (ai,bi), 其中 a i a_i ai b i b_i bi 均是正整数 ( 1 ≤ i ≤ n ) (1 ≤ i ≤ n) (1in), 订单 ( a i , b i ) (a_i ,b_i) (ai,bi)希望在时间 b i b_i bi之前获得 a i a_i ai件产品。工厂的生产能力为每个时间单位生产 1 件产品。工厂希望拒绝最少数量的订单, 并恰当地排序剩下的订单使得剩下的订单均能够被满足。试设计一个贪心算法求解上述问题。

解:贪心算法:每次选择 b i − a i b_i-a_i biai最大的元素
贪心选择性:假设有优化解 S S S,其 b i b_i bi中最大的元素是 b j b_j bj,若 b j − a j b_j-a_j bjaj n n n 个订单 ( a i , b i ) (a_i ,b_i ) (ai,bi) b i − a i b_i-a_i biai最大的元素,则成立,否则 S ′ = S − { j } + { i } S'=S-\{j\}+\{i\} S=S{ j}+{ i}那么 S ′ S' S中是相互独立且含有 b i − a i b_i-a_i biai最大的一个优化解。
优化子结构: S ′ ′ = S − { i } S''=S-\{i\} S=S{ i}是剩余订单的优化解,如不然,存在一个 S ′ ′ ′ S''' S使得订单数量更大。 ∣ S ′ ′ ′ + { i } ∣ > ∣ S ′ ′ + { i } ∣ > ∣ S ∣ |S'''+\{i\}|>|S''+\{i\}|>|S| S+{ i}>S+{ i}>S,与 S S S是优化解矛盾。

7.输入 n n n 个区间 [ a i , b i ] [a_i ,b_i] [ai,bi], 其端点满足 1 ≤ a i ≤ i ≤ b i ≤ n 1 ≤ a_i ≤ i ≤ b_i ≤ n 1aiibin, 试设计一个贪心算法选出最少区间覆盖 [ 1 , n ] [1,n] [1,n]

解:这道题端点满足 1 ≤ a i ≤ i ≤ b i ≤ n 1 ≤ a_i ≤ i ≤ b_i ≤ n 1aiibin就很诡异,按道理只存在一个区间覆盖和两个区间覆盖的情况,只要扫一遍就行了。感觉不存在贪心。

参考:哈工大算法设计与分析PPT

你可能感兴趣的:(算法)