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

為你寫詩

c/c++
隨筆 - 32, 文章 - 0, 評(píng)論 - 3, 引用 - 0
數(shù)據(jù)加載中……

最長(zhǎng)遞增子序列dp

原創(chuàng)  動(dòng)態(tài)規(guī)劃 (DP) 之 最長(zhǎng)遞增子序列(Longest Increase Subsequence)

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

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

其實(shí)這個(gè)問題和前面的最長(zhǎng)公共子序列問題還是有一定的關(guān)聯(lián)的。假設(shè)我們的初始的序列S1。那我們從小到大先排序一下。得到了S1'。這樣我們?cè)偾騍1和S1'的最長(zhǎng)公共子序列就可以知道答案了:)是不是有點(diǎn)巧妙啊。這個(gè)過程還是比較直觀的。但是這個(gè)不是這次要說的重點(diǎn),這個(gè)問題有比較傳統(tǒng)的做法的.

我們定義L(j)是一個(gè)優(yōu)化的子結(jié)構(gòu),也就是最長(zhǎng)遞增子序列.那么L(j)和L(1..j-1)的關(guān)系可以描述成

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

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

  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. }  

 

和以往的代碼有些類似,這里還有一些輔助的二維數(shù)組p用來回溯最長(zhǎng)的這個(gè)subsequence.這整個(gè)算法的時(shí)間復(fù)雜度達(dá)到了O(n∧2).當(dāng)然存在一些nlog(n)的實(shí)現(xiàn).但不是動(dòng)態(tài)規(guī)劃的重點(diǎn),這里就不說明了.

重點(diǎn)可以講的是這個(gè)問題的擴(kuò)展.下面的兩個(gè)問題也是很經(jīng)典的問題.

問題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.)

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

圖示說明

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

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

問題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.

這個(gè)問題的簡(jiǎn)要描述就是有若干個(gè)不同的箱子.你需要把他疊放的盡量的高.但是箱子的擺放必須滿足大的在下面,小的在上面的原則.箱子可以旋轉(zhuǎn)且數(shù)量不限.要求給出一組箱子就能求出能擺放的最大高度. 其實(shí)這個(gè)問題也是一個(gè)最長(zhǎng)遞增子序列的問題.只是隱藏的更深一點(diǎn). 因?yàn)橄渥涌梢苑D(zhuǎn)的緣故.我們首先定義我們的箱子的長(zhǎng)寬高分別是h,w,d.為了避免重復(fù)計(jì)算,我們約定w<=d.這樣每個(gè)箱子可以改成3個(gè)箱子.這樣我們就不用在考慮旋轉(zhuǎn)的問題了.第一步,我們先把箱子按照w*d的值來排序.(為社么要排序讀者可以自己想想).然后我們的模型就開始用H(j)來表示第j個(gè)箱子時(shí)這個(gè)箱子的高度.記得最長(zhǎng)遞增子序列的約束條件是Ai<Aj.這里的條件只是改成了對(duì)應(yīng)的di<dj&&wi<wj.同時(shí)原來的+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) 評(píng)論(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>
            亚洲日本中文字幕区| 亚洲一区影音先锋| 一本一本久久| 日韩午夜在线观看视频| 亚洲欧洲三级电影| 亚洲国产专区| 亚洲国产裸拍裸体视频在线观看乱了| 国产视频在线观看一区二区| 国产日韩精品入口| 国产日韩精品电影| 亚洲国产欧美精品| 99精品99| 亚洲欧美综合国产精品一区| 久久精品一区二区| 欧美电影免费网站| 日韩小视频在线观看专区| 亚洲视频一区二区免费在线观看| 亚洲嫩草精品久久| 狂野欧美激情性xxxx| 欧美激情一区二区三区全黄| 国产精品久久久久久久久久免费看| 国产精品素人视频| 亚洲国产精品成人精品| 亚洲一区二区日本| 久久午夜激情| 国产欧美一二三区| 久久精品天堂| 欧美精品一区二区三区在线播放 | 国产日本亚洲高清| 亚洲夫妻自拍| 亚洲欧美国内爽妇网| 久久亚洲欧洲| 亚洲特级片在线| 久久亚洲欧美国产精品乐播| 欧美日韩精品免费在线观看视频| 国产欧美日韩一级| 99精品国产一区二区青青牛奶| 亚洲免费视频成人| 欧美激情在线有限公司| 亚洲欧美日韩综合aⅴ视频| 欧美成人高清视频| 国产亚洲精品一区二区| 亚洲性人人天天夜夜摸| 欧美风情在线| 久久精品av麻豆的观看方式| 国产精品日本一区二区| 一区二区三区日韩精品视频| 欧美aaaaaaaa牛牛影院| 午夜影院日韩| 国产精品私房写真福利视频| 亚洲视频在线观看视频| 欧美国产丝袜视频| 久久久久久日产精品| 国产偷久久久精品专区| 午夜久久tv| 一本到12不卡视频在线dvd| 欧美精品一区二区在线播放| 91久久一区二区| 欧美激情第10页| 久久综合综合久久综合| 亚洲第一区在线| 免费观看在线综合色| 久久亚洲精品一区二区| 亚洲国产精品123| 欧美激情一区二区三区成人 | 老牛影视一区二区三区| 国内外成人免费激情在线视频网站 | 亚洲国产日韩一级| 欧美影片第一页| 国产日韩欧美中文在线播放| 欧美一区二区三区免费观看视频 | 国产精品成人播放| 亚洲日本电影在线| 亚洲福利国产精品| 欧美激情欧美狂野欧美精品| 亚洲高清自拍| 欧美激情视频给我| 欧美激情国产日韩| 在线一区二区日韩| 在线一区亚洲| 国产欧美一区二区精品性色| 午夜精品福利在线观看| 欧美一区视频在线| 亚洲高清在线播放| 亚洲美女av在线播放| 国产精品久久国产精品99gif| 亚洲欧美国产精品va在线观看| 亚洲欧美日韩综合aⅴ视频| 激情文学综合丁香| 亚洲人成网站影音先锋播放| 国产精品日本欧美一区二区三区| 久久精品视频99| 美女视频黄a大片欧美| 一区二区国产在线观看| 亚洲欧美国产不卡| 在线欧美三区| 一区二区三区免费网站| 国产亚洲精品aa午夜观看| 欧美大片网址| 国产精品美女久久久久久2018| 久久综合久色欧美综合狠狠 | 亚洲国产你懂的| 国产精品网站在线| 亚洲级视频在线观看免费1级| 国产精品男女猛烈高潮激情| 美玉足脚交一区二区三区图片| 欧美日韩国产区一| 久久在线91| 国产精品久久久久国产精品日日 | 在线欧美一区| 亚洲一区二区少妇| 亚洲人成在线播放| 久久9热精品视频| 亚洲一区二区三区四区五区午夜| 久久精品女人的天堂av| 亚洲欧美精品在线| 欧美剧在线免费观看网站| 久久亚洲春色中文字幕| 国产精品麻豆成人av电影艾秋| 亚洲激情欧美| 亚洲国产精品一区二区久| 午夜亚洲伦理| 午夜精品av| 欧美日韩亚洲在线| 亚洲第一精品福利| 亚洲国产成人在线视频| 欧美成人在线网站| 一区二区三区在线观看欧美| 美女任你摸久久| 亚洲欧洲99久久| 久久久久久婷| 久久国产婷婷国产香蕉| 欧美日韩一本到| 亚洲国产成人一区| 影音先锋日韩资源| 久久精品亚洲乱码伦伦中文 | 欧美日韩中文字幕在线| 亚洲韩日在线| 日韩视频不卡| 女同性一区二区三区人了人一| 久久天堂精品| 国语自产在线不卡| 久久成人免费电影| 久久人人97超碰精品888| 国内精品久久久久久| 久久久久久久激情视频| 欧美v国产在线一区二区三区| 亚洲成人中文| 欧美激情免费在线| 一区二区三区欧美| 欧美一区成人| 精品成人在线观看| 麻豆久久久9性大片| 亚洲精品在线电影| 亚洲免费视频在线观看| 国产一区二区三区久久久 | 国产三级欧美三级日产三级99| 亚洲一区影院| 久热精品在线| 日韩系列在线| 国产精品狼人久久影院观看方式| 亚洲主播在线观看| 狼人天天伊人久久| 亚洲精品一二| 国产精品久久久久久亚洲毛片| 香蕉成人久久| 欧美成人激情在线| 一区二区三区成人| 国产精品一区三区| 久久综合给合| 99精品国产福利在线观看免费| 午夜精品国产| 最新高清无码专区| 国产精品美女一区二区| 久久精品国产亚洲5555| 亚洲精品一区二区三区99| 欧美亚洲在线观看| 91久久精品国产| 国产精品亚洲一区| 欧美 日韩 国产 一区| 亚洲欧美日韩国产精品 | 久久久久久网站| 99在线精品视频在线观看| 久久全球大尺度高清视频| 9色国产精品| ●精品国产综合乱码久久久久| 欧美日韩一区二区欧美激情| 久久久女女女女999久久| 一区二区三区国产| 欧美激情一区在线观看| 久久天天狠狠| 久久久国产成人精品| 亚洲一区二区三区四区中文| 亚洲国产老妈| 激情视频一区二区| 国产日韩欧美高清| 午夜精品美女自拍福到在线 | 久久亚洲精品一区二区| 亚洲一区二区欧美日韩| 亚洲国产另类久久精品|