ZZULI - 程式設計師的揹包(最長上升子序列+二分優化)
阿新 • • 發佈:2018-12-26
題目連結:http://acm.zzuli.edu.cn/problem.php?id=2485
時間限制: 1 Sec 記憶體限制: 256 MB
題目描述
眾所周知,每個程式設計師都有一個揹包,裡邊裝著膝上型電腦(才不是為了隨時改bug呢),耳機,移動電源,switch等。現在,L同學有一個揹包,這個揹包比較奇特,首先它的空間特別大,其次呢,它裝東西要遵循一個規則:裝的東西的重量只能遞增。畢竟這是個四次元口袋嘛,哈哈。現在,L同學面前有一個傳送帶,傳送帶上會有很多東西依次傳過來,L同學只可以選擇是否把這個物品放進四次元揹包。L同學用預知能力得知了這些物品的重量(這裡假設質量可能為負質量),那麼他最多能往揹包裡裝多少東西呢?
輸入
第1行:1個數N,N為物品的數量(2 <= N <= 50000)
第2 - N + 1行:每行1個數,對應物品的重量(-10^9 <= S[i] <= 10^9)
輸出
最多能裝進揹包的物品的數量
樣例輸入
8
5
1
6
8
2
4
5
10
樣例輸出
5
解題思路
讀懂題意就能知道,這是一道最長上升子序列的模板題,套一下最長上升子序列的優化模板就行了。
#include <stdio.h> #include <string.h> int a[50010], dp[50010]; int search(int x, int l, int r) { while (l < r) { int mid = l + (r - l) / 2; if (dp[mid] >= x) r = mid; else l = mid + 1; } return l; } int LIS(int a[], int n) { int p, len = 1; memset(dp, 0, sizeof dp); dp[0] = a[0]; for(int i = 1; i < n; i++) { if (a[i] >= dp[len - 1]) dp[len++] = a[i]; else { p = search(a[i], 0, len - 1); dp[p] = a[i]; } } return len; } int main() { int n; while (~scanf("%d", &n)) { for (int i = 0; i < n; i++) scanf("%d", &a[i]); printf("%d\n", LIS(a, n)); } return 0; }