O(N2)写法:
memset(dp, 0, sizeof(dp))
for(i = 0; i < n; i++) {
dp[i]= 1;
for(j= 0; j < i; j++) {
if(s[j]< s[i]) dp[i] = max(dp[i], dp[j] + 1);
}
}
O(nlogn)写法1:( dp[i]存长度为i + 1的上升子序列中末尾元素的最小值)
fill(dp, dp + n, inf);
for(i = 0; i < n; i++) {
*lower_bound(dp,dp + n, a[i]) = a[i];
}
printf(“%d\n”, lower_bound(dp, dp + n, inf)– dp);
O(nlogn)写法2:dp[i]存长度为i的上升子序列中末尾元素的最小值,下标从1开始
intk = 1;
b[1]= a[1];
for(i= 2; i <= n; i++) {
if(a[i]> b[k]) {
b[++k]= a[i];
}
else{
char*pos = lower_bound(b, b + k,a[i]);
*pos= a[i];
}
}
printf("%d\n",k);
理解算法思想:http://blog.youkuaiyun.com/joylnwang/article/details/6766317
几个题目:
nyoj 17 :http://acm.nyist.net/JudgeOnline/problem.php?pid=17
怎么写都可以过
poj 3903 http://poj.org/problem?id=3903
poj 2533 http://poj.org/problem?id=2533
两道LIS裸题,nlogn 都可以过
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int a[100100], b[100100];
int main() {
int n;
while(~scanf("%d", &n)) {
int i, j;
for(i = 0; i < n; i++) {
scanf("%d", a + i);
}
int k = 0;
b[0] = a[0];
for(i = 1; i < n; i++) {
if(a[i] > b[k]) {
b[++k] = a[i];
}
else {
*lower_bound(b, b + k, a[i]) = a[i];
}
}
printf("%d\n", k + 1);
}
return 0;
}