日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CLRS 16.2贪心算法的原理

發布時間:2024/3/13 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CLRS 16.2贪心算法的原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

16.2-1
此處證明的思想是假設有一個最優解,然后可以由貪心算法得到此最優解。
S={1,2,...,n} 個商品,并已經按平均價值從高到底排序,即 viwivi+1wi+1 。令 A 是分數背包的一個最優解,并假定解里面也是按照平均價值從高到底排序。假設總重量和最優解的總價值分別是 W,V。令 B 是從 S 中按照貪心算法求解得的解。
1) 總重量 Ww1 :顯然裝入第一個商品得到最優解;
2) 總重量 W>w1 :在 A 中前幾個商品加起來為 w1 重的商品(這里的幾個可能是一個,也可能是多個,還可能是某一個商品的其中一部分)。令 B=A?{Aw1}+{w1} (即將 A 中的 w1 重的東西換成第一個商品的 w1 重量)。此時 A 的價值 {w1}+{} B 的價值是 {w1}+{}。由于 w1 的價值肯定是小于等于 v1 (此商品全部裝進去才有 v1 的價值)。因為 A 是最優解,所以 {w1}=v1(否則換了之后價值肯定提高, A 就不是最優解,矛盾)。這樣 A 的價值就和 B 的價值一樣,而 A 是最優的,則 B 也是最優的。
然后遞歸求解問題,求解 S n?1 個商品,包最大重量為 W?w1 。最后得到貪心算法的最優解。

附上分數背包的簡單實現:

#include <iostream> #include <algorithm> using std::cout; using std::endl;struct goods {int weight;int value;goods():weight(0),value(0){} };bool cmp(goods a,goods b) {return a.value/a.weight > b.value/b.weight; }int greedy(goods *array,int n,int weight) //返回最終價值 {std::sort(array,array + n,cmp);int res = 0;for(int i = 0; i < n; i++){if(weight >= array[i].weight){res += array[i].value;weight -= array[i].weight;}else if(weight > 0){res += weight * (array[i].value / array[i].weight);weight = 0;break;}}return res; }int main() {int v[] = {60,100,120};int w[] = {10,20,30};goods ia[3];for(int i = 0; i < 3; i++){ia[i].value = v[i];ia[i].weight = w[i];}cout << "Value is " << greedy(ia,3,50) << endl;return 0; }

16.2-2
根據書上所說,0-1背包具有最優子結構性質,若商品 i 的重量大于剩余可裝重量,我們將商品 i 從方案中刪除,否則解決方案是剩余商品重量不超過 W?wi 的價值最高方案與不選商品 i 且剩余重量不超過 W 的價值最高方案的最大者。
c[i,w] 是商品 1,...,i 且重量是 w 的解決方案價值,則:
c[i,w]=???0c[i?1,w]max(vi+c[i?1,w?wi],c[i?1,w])if i=0 or w=0if w_i>wif i>0 and w≥w_i
算法輸入是最大重量 W n 個商品以及兩個序列 v=[v1,v2,...,vn],w=[w1,w2,...wn]

DYNAMIC-0-1-KNAPSACK(v,w,n,W)let c[0..n, 0..W]? be a new arrayfor w = 0 to Wc[0,w?] = 0for i = 1 to nc[i,0]? = 0for w = 1 to Wif wi≤wif v_i + c[i-1,w-wi]? > c[i-1,w?]c[i,w?] = v_i + c[i-1,w-wi] ?else c[i,w]? = c[i-1,w?]else c[i,w]? = c[i-1,w?]

時間復雜度是 Θ(nW)

16.2-3
按照重量從低到高裝入即可。設解決方案是 x=(x1,x2,...,xn) ,且 w1w2...wnv1v2...vn 。令 j 表示第一個沒被裝入的商品下標,所以 1..j?1 的商品全部裝入, j...n 的商品都沒轉入,現假設用 j...n 的某個商品替換 1...j?1 中的某個商品,此時背包的價值下降且容量變小。

16.2-4
思想就是選擇走最長的距離再補水,也就是說剩余的水不足以到達下一個補給點時就補水,否則就不補水。證明就略了。

16.2-5
算法如下:
1) 在點集中選取最小的點;
2) 取以該點為左起點的單位閉區間,然后從點集中去掉包含在該單位閉區間的所有點;
3) 重復1)-2),直到所有的點處理完畢;那么2)得到的單位閉區間集合A即為所求。

證明:首先,根據第二步肯定能得到一個解 A ,這個解包含所有的點。假設有一個最優解 B。用以最小點為左起點的單位閉區間代替 B 中包含該最小點的單位閉區間, 得到的新的解不會比 B 更差,即 A 也是最優解。

int interval(double *x,int n)//返回區間個數 {bool *isVisit = new bool[n];for(int i = 0; i < n; ++i)isVisit[i] = false;int res = 0;for(int i = 0; i < n; ++i){if(!isVisit[i]){isVisit[i] = true;++res;double max = x[i] + 1;for(int j = i + 1; j < n; ++j){if(x[j] > max)break;else isVisit[j] = true;}}}return res; }

16.2-6
先求每個商品的平均價值 avgi=vi/wi,選擇一個物品作為主元 m=avgm ,對所有物品進行Paitition操作,時間是 O(n) 。將平均價值 avg 分為三個集合 L={ai:avgi<m},E={aiavgi=m},G={ai:avgi>m} 。分別對 G,E,L 中元素求重量和得 SG,SE,SL
1. 如果 W<SG , 則令物體的集合為 O=G ,對集合 O 遞歸進行上述過程。
2. 如果 SGWSG+SE,則將集合 G 中的元素都放入包中,并將集合 E 總元素盡可能多的放入包中,結束。
3. 如果 SG+SE<W , 將 G,E 中元素放入包中。令物體集合 O=L ,總重 W=W?SG?SE 。遞歸進行上述過程。
每次遞歸都花費線性時間,子問題變成原來的一般規模,運行時間為 T(n)T(n/2)+Θ(n) ,得到 T(n)=O(n)

16.2-7
集合 A,B 按照非遞增的順序排序即可。
證明:對于任意的下標 i<j ,考慮 abii,abjj ,我們要證明 abiiabjjabjiabij 。由于集合按照非遞增順序排列,所以 aiaj,bibj ,又 ai,aj 是正數且 bi?bj0 ,得 abi?bjiabi?bjj ,兩邊同乘 abjiabjj abiiabjjabjiabij

總結

以上是生活随笔為你收集整理的CLRS 16.2贪心算法的原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。