2021.7.23 刷題記錄
阿新 • • 發佈:2021-07-14
#include <iostream> #include <cstdio> using namespace std; const int N = 1e5+5; int n; int h[N]; int d[N]; //d[i]: 表示長度為i的遞增序列的末尾的最小值, 一定遞增 int len = 0; int main() { scanf("%d", &n); for(int i = 0; i < n; ++ i) { scanf("%d", h+i); } // d[0] = -INF; for(int i = 0; i < n; ++ i) { //尋找大於等於h[i]的最小的數 int l = 1, r = len+1; //l==r==len+1表示拓展新的長度 while(l < r) { int mid = l+r>>1; if(d[mid] >= h[i]) { r = mid; } else { l = mid+1; } } d[l] = h[i]; len = max(len, l); } printf("%d\n", len); return 0; }
#include <iostream> #include <cstdio> using namespace std; const int N = 105; int n; int h[N]; int dp[N]; //dp[i]: 以h[i]結尾的上升子序列最大長度 int rdp[N]; //從右往左看的dp int main() { scanf("%d", &n); for(int i = 1; i <= n; ++ i) { scanf("%d", h+i); } dp[1] = 1; for(int i = 2; i <= n; ++ i) { dp[i] = 1; for(int j = 1; j < i; ++ j) { if(h[i] > h[j]) { dp[i] = max(dp[i], dp[j]+1); } } } rdp[n] = 1; for(int i = n-1; i >= 1; -- i) { rdp[i] = 1; for(int j = n; j > i; -- j) { if(h[i] > h[j]) { rdp[i] = max(rdp[i], rdp[j]+1); } } } int ans = 0; for(int i = 1; i <= n; ++ i) { ans = max(ans, dp[i]+rdp[i]-1); } printf("%d\n", n-ans); return 0; }