• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天秤座的唐風

            總會有一個人需要你的分享~!- 唐風 -

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              13 隨筆 :: 0 文章 :: 69 評論 :: 0 Trackbacks
              假設某大學有一個活動室,我是這個活動管理員。某天,有6個社團都提出了使用活動室的要求,并告知了他們希望使用活動室的時間段(他們之間相互不知道對方的要求,因此時間安排是沒有相互商量過的,可能有重疊)。活動室不能同時被兩個以上社團使用。作為管理員,我無法每次都滿足所有人的要求,但我想盡量提高活動室的使用率,那么,我如何選取某幾項活動,使得活動室的使用時間最長呢?

             

              如上圖,假設上圖是某一次這些社團的要求(假設0是正午12點),各顏色條分別是各個社團的使用時間計劃。那么,我應該如何分配活動室呢?顯然,如果給了社團5,其它社團就不能再使用該活動室了,這時活動室的使用時間是從2點到8點,共使用了6個小時。但這不是最長的使用時間組合。如果將活動室分配給1、3、4、6,那么除了4點到5點之間活動室是空的之外,其它時間活動室都被使用了,一共使用時間是8個小時。

            (其實在《算法導論》一書的第16章第一節中,也提到一個活動選擇問題。這里說的活動選擇問題與書中的不一樣。這兩個問題要求不一樣。那個問題將在貪婪算法相關的內容中討論) 

            使用蠻力法,不會是一種好的方法。這一點就不過多論證了。

            這是個最優化問題。我們探索下,會發現這個問題的最優解,是有可能表示成子問題最優解的遞歸解的。假設Tij是一個從i點到j點的時間段,這個時間段內,最長的使用時間是Sij。Sij的計算中用到的活動,必須是要求整個活動時間被包括在Tij中的,不能越過這個時間限。我們就稱Vij是這樣一個集合,其中包含了所有時間范圍被完全包含在Tij范圍內的活動。

            假設對于i點到j點Tij,如果i=j,那么很顯然Sij就是0。如果i不等于j,那么最長使用使用時間Sij可能是j-i個小時,也就是有一個活動從i點一直搞到j點,那么挺好,就選擇這個活動就行了。但如果不存在這么長時間的活動,那么,我們可以試著把這個時間分成兩個部分Tik和Tkj,它們分別最長的使用時間是Sik和Skj。令S'=Sik+Skj,我們知道,當k從i到j依次取值時,可以得到各組不同的Sik和Skj,Sij肯定是S'中取最大的那個值。為什么呢?因為如果沒有一個在Tij時間內段的活動能充滿整個Tij時間段的話,那么Vij內的任何一個活動單獨放到Tij時間段內,那么在這個時間段的前端和后端,至少會出現一個空白的沒被使用的時間,如下圖:

             


                所以,直感上看,就可以把空白的時間段取出來,看這個時間段內還能不能再按排一些活動。只要沒有一個活動可以填滿整個時間段,那么最大使用時間就是Vij內多個活動時間拼接成的。那么對于從i到j內的每一個時間點k,這個點左右兩邊Tik和Tkj內會分別安排一些活動(因為每個活動都是從整點開始到整點結束,而且各活動使用活動室的時間也不能重疊。但可能Vik或Vkj會為空),就分別能得到Sik和Skj。只要對每一個可能的k值進行檢查,那么最大時間肯定就是其中的一個。

            因此,我們可以得出Sij的計算方法:

            1. 如果i=j,則 Sij=0
            2. 否則,如果存在一個活動的時候長度恰好為Tij,則Sij=j-i
            3. 否則,Sij=max{Sik+Sij} ,其中、k從i到j依次取值。

            現在,我們已經得到了這個問題最優解的一個遞歸形式的解。遞歸式中包含了子問題的最優解。(關于子問題是否是最優解,可以用《算法導論》中的"剪切粘貼法"來考慮)。這是能用動態規劃來解決的問題的第一個特征。

            然后再看,如果我們根據這個遞歸直接翻譯寫出遞歸程序,那么,對于會出現很多重復的計算。比如,當我們計算S09時,會用到S01、S02、S03、S04、......、S07、S08,再計算S08時,又會用到S01、S02、S03、S04、......、S07以此類推,這個表達式中存在非常多的重復計算,計算量很大。嗯,有很多重疊的子問題,這是能用動態規劃來解決的問題的第二個特征。

            那么,根據動態規劃的方法,就應該用從底向上的方法來解決這個問題,先計算小區間的值,并存儲起來,然后再利用已經得到的小區間的值來計算大區間的值。最終得到原問題的最優解。如下圖:
             


                格子[i,j]表示從i點到j點,最大利用時間值是多少。灰掉的部分是無效值,因為此時i值大于j值,沒有實際意思。這個表,我們從左到右計算每一列的值,就是用的從底向上的方法,最終可以地推出結果[0,9]的值是8.

            在計算最大時間的過程中,將每次使得Sij最大時的K值記錄下來,存儲到K[i][j]中去,Sij得出來之后,就可以到出一個K[i][j]的表,根據這個表,可以得到如何不斷地將時間劃分成最優的兩段,直至時間段內有活動充滿該時間段,或是時間段內不存在任何活動。有了這個時間劃分,我們就可以從這些時間段中分別相應的活動,這樣,問題就最終得到了解決。

            posted on 2009-07-15 21:48 唐風 閱讀(1248) 評論(0)  編輯 收藏 引用 所屬分類: 算法訓練場
            精品999久久久久久中文字幕| 色偷偷88888欧美精品久久久| 久久99热国产这有精品| 国产91色综合久久免费| 99久久国产综合精品五月天喷水 | 久久影院综合精品| 国内精品久久久久久99蜜桃| 97精品伊人久久大香线蕉app| 久久精品无码一区二区app| 亚洲国产成人久久一区久久| 亚洲AV成人无码久久精品老人| 国产精品嫩草影院久久| 久久天天婷婷五月俺也去| 国产精品久久久久影院色| 色婷婷狠狠久久综合五月| 国产一久久香蕉国产线看观看| 成人综合久久精品色婷婷| 伊人久久大香线蕉精品| 蜜臀av性久久久久蜜臀aⅴ麻豆 | 亚洲国产精品久久久久婷婷老年| 久久久久香蕉视频| 91精品国产综合久久久久久| 久久受www免费人成_看片中文 | 色综合久久中文综合网| 伊人久久大香线蕉亚洲五月天| 久久久久无码专区亚洲av| 久久本道伊人久久| 久久天堂AV综合合色蜜桃网 | 国产精品无码久久综合网| 国产亚洲综合久久系列| 久久精品国产AV一区二区三区 | 久久99久久99小草精品免视看| 亚洲国产精品无码成人片久久| 久久免费视频6| 欧美久久天天综合香蕉伊| 久久99精品久久久久久秒播| 99久久精品免费观看国产| 国产精品视频久久| 久久精品国产影库免费看| 青青青伊人色综合久久| 久久青青草原国产精品免费|