關於最長遞增子串行的實際應用 動態規劃

2021-09-01 07:52:34 字數 3125 閱讀 8732

a.

b.

1.對(中問題6:最長遞增子串行的改進,減少時間複雜度

演算法的思想:

它不是使用的動態規劃法,而是普通的演算法思想,就是在陣列中直接儲存最長遞增子串行,在迴圈的過程中不斷的查詢插入位置,直到最終找到。下面列出實現的過程:

從上面的過程可以看出該演算法的實現過程,在查詢sub合適插入位置的時候,使用了二分查詢,提高了查詢速度,這個演算法本身也比前面利用動態規劃法簡單,但是該演算法複雜之處不在演算法

而在演算法正確性的證明!,演算法證明見:

**:

#include #include using namespace std;

const int min = -32768;

/** *a :原始陣列

*sub :最終獲取的最大遞增子串行(注意,sub[0]是哨兵,結果從1開始)

*length :陣列長度

**/int longestsub(int* a, int* sub, int length)

return len;

}int main();

int* sub = new int[13];

memset(sub,0,sizeof(int));

int length = longestsub(a,sub,13);

cout<

不過其結果和改進之前的有些不同,前面是,改進之後是結果都是正確的!

2.實際應用的兩個例子

a.造橋問題

問題描述:

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

問題分析:

首先,這是乙個動態規劃的問題,即解答有許多中,尋找乙個最優的解決方案。

其次,問題抽象,就是怎樣將這個問題抽象成乙個數學模型進行解決

第一步:就是搞清楚問題是什麼?-------就是對號入座a對應於b的序號,這樣的解決方案有許多如1,5,4和2,5,4以及1,3

第二步:抽象-------抽象成兩個陣列s1(1,2,5,4,3), s2(2,1,3,5,4),然後找s1和s2中相同的數字,且序號必須在陣列下標遞增,找出最多的對數

(即s1中的1對應了s2中的1,s1中的2對應了s2中的2,雖然s1中的下標是1,2 但是在s2中的下標是2,1沒有遞增,故而是不行的---更簡單的說就是上面圖不能交叉)

第三步:找規律--------這是最難的,如何才能從中找到突破口,我們在尋找的過程中發現,聯絡s1和s2的橋梁是什麼?就是組成對的兩個數在各自陣列中的下標

那我們把這些下標都寫出來,只是寫一方就可以了從s1到s2的,就設為s3(2,1,4,5,3)---就表示s3[0]=2表示s1陣列第乙個值對應與s2中的第二個值(這個2就是在s2中的下標),

從而依次就把s3寫出來了,這樣找對數最多,而s3表示的是連線時對方的下標,那麼是不是只要下標遞增就不會交叉了?事實就是這樣!!

就是找s3中的最長遞增陣列,這裡就是或者

第四步:寫**-------既然突破口找到了,**就不是問題了

**/**

*建橋問題

**/#include #include using namespace std;

/** *建立建橋索引陣列

*a : 原始陣列a

*b : 原始陣列b

*c :建立的索引陣列

*length :陣列長度

*/void build(const int* a, const int* b, int* c, int length)

} }int m=0,k=0;

for (int i=1;i<=n;i++)

delete t;

delete p;

p = null;

t = null;

}int main();

int b = ;

int length = sizeof(a)/sizeof(int);

//索引陣列

int* c = new int[length];

//儲存最終結果

int* sub = new int[length];

memset(sub,0,sizeof(int));//初始化sub

memset(sub,0,sizeof(int));//初始化sub

build(a,b,c,length);

longestincreasesub(c,length, sub);

printresult(b,sub, length);

delete c;

delete sub;

c = null;

sub = null;

return 0;

}

b.疊箱子問題問題描述:

1.一排有許多不同的箱子,長寬高不一樣

2.你需要把他疊放的盡量的高.但是箱子的擺放必須滿足大的在下面,小的在上面的原則

3.箱子可以任意旋轉(這就意味著你要用乙個箱子的時候,旋轉到合適位置)

問題分析:

具體分析見圖:

注1:盒子要比上面的大--準確的說,是wi>wj && di>dj,單獨使用si>sj不準確,因為可能很長但很窄,不和題目要求

為了滿足要求,我們人為規定,w<=d(輸入時確定或者後來處理),這樣就不用擔心這個問題了,使用si>sj就滿足要求。

注2:記住盒子可以旋轉,意味著每個盒子可以有三個面可以使用,旋轉數量不限。

注3:本體關鍵是建立模型,列出動態規劃的方程

**:

/**

* *疊箱子問題

*/#include #include #include #include using namespace std;

//定義乙個箱子結構體

struct box;

//排序比較器

bool boxcompare(const box& a, const box&b)

//最高的堆疊高度演算法

int highestbox(const vector& b)

最長遞增子串行

這是微軟實習生筆試遇到的,題意 求乙個陣列中最長遞增子串行的長度。要求選擇該題最好演算法的時間複雜度和空間複雜度。答案 時間複雜度o nlgn 空間複雜度o n 這題明顯用動態規劃來解。假設在目標陣列array 的前i個元素中,以array i 元素為最大元素的遞增子串行的長度是lis i 那麼 遞...

最長遞增子串行

最長遞增子串行又叫做最長上公升子串行 子串行,正如lcs一樣,元素不一定要求連續。本節討論實現三種常見方法,主要是練手。題 求乙個一維陣列arr i 中的最長遞增子串行的長度,如在序列1,1,2,3,4,5,6,7中,最長遞增子串行長度為4,可以是1,2,4,6,也可以是 1,2,4,6。方法一 d...

最長遞增子串行

最長遞增子串行 求乙個字串的最長遞增子串行 如 dabdbf最長遞增子串行就是abdf,長度為4 這是一道基本的動態規劃求解的題目,與此類似的還有 最長公共子串行 分析 用一維陣列dp i 來儲存以a i 為末元素的最長遞增子串行的長度,那麼dp i 至少為1 即包含它本身 往前尋找,如果存在a j...