青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

為你寫詩

c/c++
隨筆 - 32, 文章 - 0, 評論 - 3, 引用 - 0
數據加載中……

最長遞增子序列dp

原創  動態規劃 (DP) 之 最長遞增子序列(Longest Increase Subsequence)

原文:http://blog.csdn.net/hhygcy/archive/2009/03/02/3950158.aspx

既然已經說到了最長公共子序列,就把這個遞增子序列也說了。同樣的,這里subsequence表明了這樣的子序列不要求是連續的。比如說有子序列{1, 9, 3, 8, 11, 4, 5, 6, 4, 19, 7, 1, 7 }這樣一個字符串的的最長遞增子序列就是{1,3,4,5,6,7}或者{1,3,4,5,6,19}。

其實這個問題和前面的最長公共子序列問題還是有一定的關聯的。假設我們的初始的序列S1。那我們從小到大先排序一下。得到了S1'。這樣我們再球S1和S1'的最長公共子序列就可以知道答案了:)是不是有點巧妙啊。這個過程還是比較直觀的。但是這個不是這次要說的重點,這個問題有比較傳統的做法的.

我們定義L(j)是一個優化的子結構,也就是最長遞增子序列.那么L(j)和L(1..j-1)的關系可以描述成

L(j) = max {L(i), i<j && Ai<Aj  } + 1;  也就是說L(j)等于之前所有的L(i)中最大的的L(i)加一.這樣的L(i)需要滿足的條件就是Ai<Aj.這個推斷還是比較容易理解的.就是選擇j之前所有的滿足小于當前數組的最大值.

很容易的我們寫出了下面的代碼:

  1. // Longest_Increase_subsequence.cpp : Defines the entry point for the console application.  
  2. //  
  3. #include "stdafx.h"  
  4. #include <vector>  
  5. #include <iostream>  
  6. #include "windows.h"  
  7. /** 
  8. * Description: Calulate the longest increase subsequence 
  9. *@param s1, source sequence 
  10. *@param s2, output, longest increase sequence 
  11. */  
  12. template<typename T> void longest_increase_subsequence(const std::vector<T>& s1, std::vector<T>& s2)  
  13. {  
  14.       
  15.     int n = s1.size(); if (n<1) return;  
  16.     int m = 0;  
  17.     int k = 0;  
  18.     std::vector<unsigned int> b(n+1, 1);  
  19.     std::vector<unsigned int> p(n+1, 0);  
  20.               
  21.     for (int i=1;i<=n;i++)     
  22.     {  
  23.         for (int j=1;j<i;j++)  
  24.         {  
  25.             if ( s1[i-1] > s1[j-1] && b[i] < b[j] +1 )  
  26.             {  
  27.                 b[i] = b[j] + 1;  
  28.                 p[i] = j;  
  29.             }     
  30.         }  
  31.     }     
  32.     for ( int i=1;i<=n;i++)  
  33.     {  
  34.         if (m<b[i])  
  35.         {     
  36.             m = b[i];  
  37.             k = i;  
  38.         }     
  39.     }     
  40.     s2.resize(m);  
  41.     while (k>0)  
  42.     {  
  43.         s2[m-1] = s1[k-1];  
  44.         m--;  
  45.         k = p[k];  
  46.     }  
  47. }  
  48. int _tmain(int argc, _TCHAR* argv[])  
  49. {  
  50.     int a[] = { 1, 9, 3, 8, 11, 4, 5, 6, 4, 19, 7, 1, 7 };  
  51.     std::vector<int> seq(a, a+sizeof(a)/sizeof(a[0]));  
  52.     std::vector<int> r;  
  53.     longest_increase_subsequence(seq, r);  
  54.     for (int i=0;i<r.size();i++)  
  55.         std::cout<<r[i]<<" ";  
  56.     std::cout<<std::endl;  
  57.     system("pause");  
  58.     return 0;  
  59. }  

 

和以往的代碼有些類似,這里還有一些輔助的二維數組p用來回溯最長的這個subsequence.這整個算法的時間復雜度達到了O(n∧2).當然存在一些nlog(n)的實現.但不是動態規劃的重點,這里就不說明了.

重點可以講的是這個問題的擴展.下面的兩個問題也是很經典的問題.

問題1.造橋問題. 原題是這樣:Building Bridges. Consider a 2-D map with a horizontal river passing through its center. There are n cities on the southern bank with x-coordinates a(1) ... a(n) and n cities on the northern bank with x-coordinates b(1) ... b(n). You want to connect as many north-south pairs of cities as possible with bridges such that no two bridges cross. When connecting cities, you can only connect city i on the northern bank to city i on the southern bank. (Note: this problem was incorrectly stated on the paper copies of the handout given in recitation.)

大致就是要在一條河的南北兩邊的各個城市之間造若干座橋.橋兩邊的城市分別是a(1)...a(n)和b(1)...b(n).這里的要求a(i)只可以和b(i)之間造橋,同時兩座橋之間不能交叉.希望可以得到一個盡量多座橋的方案.

圖示說明

比如上面這張圖,初看上去讓人有些沒有思路.但是仔細一想,其實這就是一個完美的最長公共子序列的問題的變形.怎么講呢?如果把河南邊的a城市做一個排序,可以得到一個序列.如上圖,我們得到的就是S1 = {2,1,3,5,4}在這里,同時北邊也進行依次排序,得到序列S2 = {1,2,5,4,3}.進一步從南邊的第一座橋開始計算在北邊序列中的index.也就是S1中的每個值相對于S2中的位置.比如說A2在南邊是第一個在北邊是第二個,所以第一個元素是2.A1在北邊的對應位置是1.A3在北邊的對應位置是5,A5在北邊的對應位置是3,最后一個A4在北邊的對應位置是3.這樣我們就得到一個新的序列S3= {2,1,5,3,4}.這個序列的實際意義就是南邊的第幾座橋需要連接到北邊的第幾座橋.做理想的情況就是遞增的,那樣所有的橋都可以建造:)也就是說我們的造橋問題就轉化成了尋找這個序列的最長遞增子序列的問題.當然就是{1,3,4}.也就是紅線所代表的橋.

代碼不貼了,但是問題確實比較奧妙.

問題2.Box Stacking. You are given a set of n types of rectangular 3-D boxes, where the i^th box has height h(i), width w(i) and depth d(i) (all real numbers). You want to create a stack of boxes which is as tall as possible, but you can only stack a box on top of another box if the dimensions of the 2-D base of the lower box are each strictly larger than those of the 2-D base of the higher box. Of course, you can rotate a box so that any side functions as its base. It is also allowable to use multiple instances of the same type of box.

這個問題的簡要描述就是有若干個不同的箱子.你需要把他疊放的盡量的高.但是箱子的擺放必須滿足大的在下面,小的在上面的原則.箱子可以旋轉且數量不限.要求給出一組箱子就能求出能擺放的最大高度. 其實這個問題也是一個最長遞增子序列的問題.只是隱藏的更深一點. 因為箱子可以翻轉的緣故.我們首先定義我們的箱子的長寬高分別是h,w,d.為了避免重復計算,我們約定w<=d.這樣每個箱子可以改成3個箱子.這樣我們就不用在考慮旋轉的問題了.第一步,我們先把箱子按照w*d的值來排序.(為社么要排序讀者可以自己想想).然后我們的模型就開始用H(j)來表示第j個箱子時這個箱子的高度.記得最長遞增子序列的約束條件是Ai<Aj.這里的條件只是改成了對應的di<dj&&wi<wj.同時原來的+1也變成了+hi.

最后貼一下不是很好的代碼.但是大致上還是工作了:

  1. // box_stacking.cpp : Defines the entry point for the console application.  
  2. //  
  3. #include "stdafx.h"  
  4. #include <iostream>  
  5. #include <vector>  
  6. #include <algorithm>  
  7. #include <functional>   
  8. #include "windows.h"  
  9. /* 
  10. Box Stacking. You are given a set of n types of rectangular 3-D boxes,  
  11. where the i^th box has height h(i), width w(i) and depth d(i) (all real numbers).  
  12. You want to create a stack of boxes which is as tall as possible,  
  13. but you can only stack a box on top of another box if the dimensions of the 2-D base of  
  14. the lower box are each strictly larger than those of the 2-D base of the higher box.  
  15. Of course, you can rotate a box so that any side functions as its base.  
  16. It is also allowable to use multiple instances of the same type of box.  
  17. */  
  18. struct Box  
  19. {  
  20.     int h; // height;  
  21.     int w; // width;  
  22.     int d; // depth;  
  23. };  
  24. struct sizeSort: public std::binary_function <Box, Box, bool>  
  25. {  
  26.     bool operator()(const Box& b1, const Box& b2)  
  27.     {  
  28.         return b1.w*b1.d > b2.w*b2.d;  
  29.     }  
  30. };   
  31. int highest_box_stacking( const std::vector<Box>& b)  
  32. {  
  33.     // first make the box 1*2*3  
  34.     // to like this: 1*(2*3), 2*(1*3), 3*(1*2);  
  35.     // let's assume width<=depth, then we can get 3*n boxes.  
  36.     if (b.size()<1)   
  37.         return 0;  
  38.     std::vector<Box> box (b.size()*3);   
  39.     for (int i=0;i<b.size();i++)  
  40.     {  
  41.         box[i*3+0].h = b[i].h;  
  42.         box[i*3+0].w = b[i].w < b[i].d ? b[i].w : b[i].d;                          
  43.         box[i*3+0].d = b[i].w < b[i].d ? b[i].d : b[i].w;                          
  44.         box[i*3+1].h = b[i].w;  
  45.         box[i*3+1].w = b[i].h < b[i].d ? b[i].h : b[i].d;                          
  46.         box[i*3+1].d = b[i].h < b[i].d ? b[i].d : b[i].h;                          
  47.         box[i*3+2].h = b[i].d;  
  48.         box[i*3+2].w = b[i].h < b[i].w ? b[i].h : b[i].w;                          
  49.         box[i*3+2].d = b[i].h < b[i].w ? b[i].w : b[i].h;      
  50.     }  
  51.     std::sort(box.begin(),box.end(),sizeSort());  
  52.       
  53.     std::vector <int> m(b.size()*3);  
  54.     m[0] = box[0].h;  
  55.     for ( int i = 1; i < box.size(); i++ )  
  56.     {  
  57.         for ( int j = 0; j < i; j++ )  
  58.         {  
  59.             if ( (box[i].w <= box[j].w) && (box[i].d <= box[j].d) && (m[i] < m[j]+box[i].h) )  
  60.                 m[i] = m[j] + box[i].h;  
  61.         }  
  62.     }     
  63.     return *std::max_element(m.begin(),m.end());  
  64. }  
  65. int _tmain(int argc, _TCHAR* argv[])  
  66. {     
  67.     std::vector<Box> box(3);  
  68.     box[0].h = 2;  
  69.     box[0].w = 3;  
  70.     box[0].d = 4;  
  71.     box[1].h = 2;  
  72.     box[1].w = 3;  
  73.     box[1].d = 1;  
  74.     box[2].h = 5;  
  75.     box[2].w = 3;  
  76.     box[2].d = 4;  
  77.     std::cout<<highest_box_stacking(box)<<std::endl;  
  78.     system("pause");  
  79.     return 0;  
  80. }  

 

posted on 2011-04-23 16:54 pp_zhang 閱讀(927) 評論(0)  編輯 收藏 引用 所屬分類: acm

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久欧美中文字幕| 亚洲人成网站色ww在线| 久久久蜜桃一区二区人| 午夜精品视频一区| 国产精品永久免费| 久久超碰97人人做人人爱| 亚洲免费视频在线观看| 国产欧美一区二区三区在线老狼 | 国产精品久久久久久模特| 亚洲——在线| 久久精品麻豆| 91久久综合亚洲鲁鲁五月天| 亚洲人体1000| 黄色精品一区二区| 99国产精品视频免费观看| 国产欧美精品| 91久久极品少妇xxxxⅹ软件| 国产精品乱码人人做人人爱| 欧美激情一区三区| 国产亚洲精品bt天堂精选| 亚洲乱码精品一二三四区日韩在线| 国产乱码精品一区二区三区五月婷| 欧美激情精品久久久六区热门 | 亚洲欧洲一区二区在线观看| 99国产精品久久久久久久成人热| 亚洲国产第一| 久久久精彩视频| 久久手机免费观看| 美日韩精品免费| 久久综合伊人| 国产日产高清欧美一区二区三区| 亚洲国产二区| 亚洲国产第一| 久久五月激情| 欧美大片免费| 影音先锋另类| 久久不射网站| 久久婷婷国产麻豆91天堂| 国产日韩av一区二区| 亚洲尤物精选| 久久精品综合网| 国产亚洲精品美女| 久久久www| 亚洲黄色视屏| 一本一本久久a久久精品牛牛影视| 久久精品毛片| 欧美激情一区三区| 日韩午夜在线电影| 国产精品第一区| 欧美一区二区三区四区夜夜大片 | 欧美在线观看视频| 欧美国产日韩免费| 一本久道综合久久精品| 国产精品第一区| 久久久久久亚洲精品不卡4k岛国| 欧美顶级艳妇交换群宴| 久色婷婷小香蕉久久| 欧美激情1区2区3区| 亚洲曰本av电影| 91久久久国产精品| 国产美女精品视频免费观看| 久久国产婷婷国产香蕉| 亚洲美女黄色| 欧美成人久久| 久久av在线| 亚洲校园激情| 亚洲电影免费在线观看| 欧美性猛交xxxx乱大交退制版| 欧美一区二区三区免费观看视频| 欧美高清在线| 久热精品视频在线观看| 亚洲自拍偷拍福利| 国产午夜精品久久久久久免费视| 欧美电影在线播放| 久久久久免费视频| 欧美在线资源| 久久国产一区| 久久成人一区| 久久成人精品电影| 日韩亚洲在线观看| 亚洲精品亚洲人成人网| 亚洲国产91色在线| 亚洲国产天堂久久综合网| 欧美国产一区二区| 欧美成人精品| 亚洲第一在线| 亚洲精品乱码视频| 在线视频亚洲一区| 午夜一区在线| 久久久久青草大香线综合精品| 久久人体大胆视频| 欧美视频日韩视频| 国产视频在线一区二区 | 在线中文字幕一区| 亚洲欧美自拍偷拍| 国产一区二区三区在线播放免费观看| 国产精品看片资源| 黄色亚洲网站| 一区二区免费在线观看| 午夜一级久久| 亚洲国产婷婷综合在线精品 | 欧美调教vk| 国语自产精品视频在线看一大j8| 亚洲激情综合| 亚洲免费在线视频| 亚洲电影下载| 亚洲午夜精品| 欧美日韩国产三级| 伊人狠狠色j香婷婷综合| 一区二区三区久久| 在线亚洲成人| 日韩一区二区免费看| 欧美在线视频免费观看| 国产精品久久久久久久电影| 亚洲精品一区二区网址| 美日韩精品免费观看视频| 久久成人精品视频| 国产欧美 在线欧美| 亚洲欧美日韩人成在线播放| 亚洲欧洲日本mm| 欧美激情一区二区三区蜜桃视频| 一区二区在线视频播放| 麻豆9191精品国产| 欧美11—12娇小xxxx| 亚洲精选一区| 亚洲最新在线| 国内精品久久久久久久影视麻豆| 久久精品亚洲一区| 久久男人资源视频| 亚洲精品在线电影| 久久久天天操| 欧美电影免费观看大全| 亚洲性线免费观看视频成熟| 亚洲一区二区三区在线观看视频 | 久久精品国产一区二区电影 | 欧美一级视频精品观看| 欧美激情自拍| 久久aⅴ国产欧美74aaa| 美女视频黄免费的久久| 亚洲一区二区在线看| 久久精品国产亚洲一区二区三区| 亚洲日韩成人| 性欧美8khd高清极品| 99视频在线精品国自产拍免费观看| 亚洲小视频在线| 一本色道久久| 美女被久久久| 免费欧美网站| 极品少妇一区二区三区精品视频 | 久久人人爽人人| 国产一区二区高清不卡| 亚洲天堂av在线免费| 一区二区三区 在线观看视频| 久久中文久久字幕| 欧美成ee人免费视频| 红桃视频国产一区| 欧美在线91| 久久久久免费视频| 国产自产女人91一区在线观看| a4yy欧美一区二区三区| 亚洲国产成人精品女人久久久| 亚洲尤物在线视频观看| 亚洲国产成人精品女人久久久| 亚洲狠狠婷婷| 亚洲精品123区| 久久久久88色偷偷免费| 性高湖久久久久久久久| 欧美日本网站| 蜜桃av一区二区| 国产真实乱子伦精品视频| 亚洲综合丁香| 久久国产精品一区二区三区| 国产精品免费小视频| 一区二区三区视频在线看| 亚洲天堂av图片| 欧美日韩在线播放一区| 欧美国产欧美综合 | 亚洲激情在线观看视频免费| 久久久久久亚洲精品不卡4k岛国| 久久一区二区三区四区| 欧美日韩免费高清| 夜久久久久久| 久久九九免费| 亚洲国产视频a| 欧美日韩一区二区在线播放| 一区二区三区四区五区视频| 久久成人精品| 亚洲国产精品一区二区久| 欧美精品成人| 亚洲欧美成aⅴ人在线观看| 久久夜精品va视频免费观看| 亚洲理论在线观看| 国产精品一香蕉国产线看观看| 欧美一区二区视频97| 亚洲第一天堂无码专区| 亚洲欧美国产视频| 亚洲国产精品va在线看黑人| 欧美视频免费| 欧美人与性动交cc0o| 欧美亚洲网站|