一道world final,描述巨長,讀完發現,就是最長下降序列,就變成很簡單的DP了,不過爲了學習那個O(nlogn)算法,再去仔細折騰了下,有兩個覺得說的很好,一個紙牌比喻,一個對於這類問題的介紹
這裏注意,因爲一般問題是最長上升子序列,所以這裏利用upper_bound, lower_bound這類二分查找的算法就需要一些技巧了,可以詳見代碼
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <deque>
using namespace std;
const int maxn= (1<<15)+3;
int a[maxn], dv[maxn];
int main(int argc, char const *argv[])
{
int kase= 0;
while (1== scanf("%d", &a[0]) && ~a[0]){
int l= 1;
while (1== scanf("%d", a+l) && ~a[l]){
++l;
}
memset(dv, -1, (l+2)*sizeof(int));
for (int i= 0; i< l; ++i){
*upper_bound(dv, dv+l, a[i], greater<int>())= a[i];
}
if (kase){
putchar('\n');
}
printf("Test #%d:\n maximum possible interceptions: %d\n", ++kase, (int)(lower_bound(dv, dv+l, -1, greater<int>())-dv));
}
return 0;
}