DP最長子序列 (常規加二分)

2021-08-15 16:54:37 字數 2436 閱讀 2322

所有的最長子序列都差不多,只是》,<,>=,<=的區別,所以要注意符號問題,之前學過常規寫法,今天又看到了乙個二分寫法,時間複雜度前者為n*n,後者為nlogn,所以學一學還是很有必要的,挑了一道自己oj上的dp水題

傳送門 :

最長不上公升子串行

常規寫法很簡單,也當是複習了

#include#include#include#include#include#include#include#include#includeusing namespace std;

int dp[1005];

int a[1005];

int main()

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

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

if(a[i] <= a[j])

dp[i] = max(dp[i], dp[j] + 1);

int ans = 0;

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

if(ans < dp[i])

ans = dp[i];

printf("%d\n",ans);

}return 0;

}

接下來就是二分寫法,有點類似於堆疊,如果有元素小於等於棧頂元素,就把該元素堆上,否則就進行「最合適的替換操作」,

一開始沒太明白,手動模擬了一下就ok,然而這道題我不會用二分,尷尬不,因為這是最長不上公升子串行,所以二分法需要返回序列中小於該元素的最大的元素下標,然而我不會,找了好久也沒有搜到。。等我熟悉熟悉再回來

但是我會求最長上公升子串行的。。。。

這道題隱藏的有些深,其實就是要求最長上公升子串行長度,自己畫個圖很容易理解

常規寫法很簡單

#include#include#include#include#include#include#include#include#includeusing namespace std;  

int num[30005];

int dp[30005];

int main()

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

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

if(num[i] > num[j])

dp[i] = max(dp[i], dp[j] + 1);

int ans = 0;

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

if(ans < dp[i])

ans = dp[i];

printf("%d\n",ans);

} return 0;

}

二分寫法:

其中二分法返回該大於元素的最小值的下標

#include#include#include#include#include#include#include#include#includeusing namespace std;

int dp[1005];

int a[1005];

int find_binary(int num, int k)

return low;

}int main()

int len = 1;

dp[1] = a[1];

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

}printf("%d\n",len);

}return 0;

}

從這裡面認識到了兩個新的函式

forwarditer lower_bound(forwarditer first, forwarditer last,const _tp& val)演算法返回乙個非遞減序列[first, last)中的第乙個大於等於值val的位置。

forwarditer upper_bound(forwarditer first, forwarditer last, const _tp& val)演算法返回乙個非遞減序列[first, last)中第乙個大於val的位置。

直接用lower_bound()會比手寫的慢一點,但是方便

這道題如果這樣寫的話**是這樣的:

#include#include#include#include#include#include#include#include#includeusing namespace std;

int dp[1005];

int a[1005];

int main()

int len = 1;

dp[1] = a[1];

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

}printf("%d\n",len);

}return 0;

}

最長遞增子串行!!!(DP ,二分)

最長遞增子串行 time limit 1000 ms memory limit 32768 k total submit 158 64 users total accepted 68 56 users rating special judge no description 給出乙個數字序列求其最長的...

飛彈攔截 最長子序列問題,二分查詢

某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷達給出...

最長非遞減子串行 dp 二分

時間限制 c c 1秒,其他語言2秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld 乙隻青蛙出去旅遊,因為中國有一句古話說的好 由簡入奢易,由奢入儉難 所以這只青蛙當看的當前景點比前面看過的景點差的時候,青蛙就會說 不開心 為了避免這只青蛙說 不開...