關於LIS和memset()函數

LIS

關於最長上升子序列問題,有兩種算法,複雜度 O(n^2) 和 O(nlogn)
導航----紫書P274,https://vjudge.net/problem/OpenJ_Bailian-2757
在這裏插入圖片描述

第一種

在這裏插入圖片描述
這一種,dp[i] = x 表示的是以i結尾的數的最長子序列是x,算法就是從第一個數開始遍歷,再對前面的數進行遍歷,再根據條件不斷地更新dp[i]的值。
這個算法的主要在於內層循環浪費時間

memset()

memset 函數是內存賦值函數,用來給某一塊內存空間進行賦值的。
頭文件:cstring 或 memory
話說剛開始使用memset的時候一直以爲memset是對每一個int賦值的,心裏想有了memset還要for循環對數組進行初始化幹嘛。但其實memset這個函數的作用是將數字以單個字節逐個拷貝的方式放到指定的內存中去。

memset(dp,0,sizeof(dp))
int 類型的變量一般佔用4個字節,對每一個字節賦值0的話就變成了“00000000 00000000 000000000 00000000” (即10進制數中的0)

memset(dp,1,sizeof(dp));
這樣你可能以爲如果你賦值1的話會讓整個dp數組裏的每一個int變成1,其實不然。
以上代碼執行後,dp數組的內容爲 00000001 00000001 00000001 00000001 轉化爲十進制後不爲1。
所以不能直接用memset()函數對數組dp進行初始化!!!

改進算法

優化在於使用二分,讓內層變成logn 的複雜度,可以利用lower_bound()函數,其複雜度是O(logn)。

思想:定義一個數組ans[i] = j; 表示長度爲i時的結尾爲j。初始化ans[1]=a[1];再遍歷數組,其中,對ans[]數組進行更新,如果a[i]>ans[len]的話,就長度加1,並把a[i]加入到數組ans中,當小於的時候,其實用到了貪心的思想,選擇一個更小的數,讓後面加入數的時候有更多的選擇,因而將小的數更新大的數。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章