求最长不上升子序列的个数即求最长上升子序列的长度
简单证明:因为在序列中的每一次数据的上升意味着最长不上升子序列有一个新的起点
#include <cstdio> #include <sstream> #include <iostream> using namespace std; const int maxn = 1e5 + 10; const int INF = 2147483640; int dp[maxn]; int a[maxn]; int bin_find1(int l, int r, int key); int bin_find2(int l, int r, int key); int main() { int i; int n = 0;//a[]长度 int len = 0; int pos; /*string line; getline(cin, line); stringstream ss(line); while(ss >> a[++n]) ; --n; */ while(~scanf("%d", &a[++n])) ; --n; dp[0] = INF; for(i = 1; i <= n; ++i) { if(a[i] <= dp[len]) dp[++len] = a[i]; else { pos = bin_find1(1, len, a[i]); dp[pos] = a[i]; } } printf("%d\n", len); //第二问 len = 0; dp[0] = -INF; for(i = 1; i <= n; ++i) { if(a[i] > dp[len]) dp[++len] = a[i]; else { pos = bin_find2(1, len, a[i]); dp[pos] = a[i]; } } printf("%d\n", len); return 0; } int bin_find1(int l, int r, int key) { int mid; while(l <= r) { mid = (l+r)>>1; if(key > dp[mid]) r = mid - 1; else l = mid + 1; } return r + 1; } int bin_find2(int l, int r, int key) { int mid; while(l <= r) { mid = (l+r)>>1; if(key <= dp[mid]) r = mid - 1; else l = mid + 1; } return r + 1; }