最長上公升子串行 nlogn

2021-06-22 16:15:32 字數 2490 閱讀 2774

最長上公升子串行中對於數ipt[i],向前遍歷,當數ipt[j]小於ipt[i] 則ipt[j]可作為上公升序列中ipt[i]的前乙個數字

dp[i] = max

若現在有兩個狀態a,b 滿足dp[a] = dp[b]且 ipt[a] < ipt[b]

則對於後面的狀態dp[a]更優  因為若ipt[i] > dp[b] 則必然ipt[i] > dp[a],反之若ipt[i] > dp[a] 卻不一定滿足ipt[i] > dp[b]

所以若只儲存狀態a  那麼也不會丟失最優解

那麼對於相同dp值,只需保留ipt最小的乙個

則  ipt值(dp=1) < ipt值(dp=2) < ipt值(dp=3).....

即此序列有序

比如  1 6 2 3 7 5

dp  1 2 2 3 4 4

當計算2時  發現dp=2的ipt值為6  則6可替換為2

同理    1 (6) 2 3 (7) 5

dp 1      2 3      4

這樣,計算時維護乙個序列即可

//#pragma comment(linker, "/stack:102400000,102400000")

//head

#include #include #include #include #include #include #include #include #include #include #include #include using namespace std;

//loop

#define fe(i, a, b) for(int i = (a); i <= (b); ++i)

#define fed(i, b, a) for(int i = (b); i>= (a); --i)

#define rep(i, n) for(int i = 0; i < (n); ++i)

#define clr(a,value) memset(a,value,sizeof(a))

//stl

#define pb push_back

//input

#define ri(n) scanf("%d", &n)

#define rii(n, m) scanf("%d%d", &n, &m)

#define riii(n, m, k) scanf("%d%d%d", &n, &m, &k)

#define rs(s) scanf("%s", s)

typedef long long ll;

const int inf = 0x3f3f3f3f;

const int maxn = 1010;

#define ff(i, a, b) for(int i = (a); i < (b); ++i)

#define fd(i, b, a) for(int i = (b) - 1; i >= (a); --i)

#define cpy(a, b) memcpy(a, b, sizeof(a))

#define fc(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)

#define eq(a, b) (fabs((a) - (b)) <= 1e-10)

#define all(c) (c).begin(), (c).end()

#define sz(v) (int)v.size()

#define riv(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)

#define rv(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)

#define wi(n) printf("%d\n", n)

#define ws(s) printf("%s\n", s)

#define sqr(x) (x) * (x)

typedef vector vi;

typedef unsigned long long ull;

const double eps = 1e-10;

const ll mod = 1e9 + 7;

int ipt[1010], dp[1010], a[1010];

int main()

cout << ans << endl;

}return 0;

}

最長上公升子串行nlog n

nlog n 的方法從很久之前就看了,愣是沒看懂,因為這個條件 現在,我們仔細考慮計算f t 時的情況。假設有兩個元素a x 和a y 滿足 f儲存lis長度 1 x y t 2 a x a y a t 3 f x f y 沒看懂,當a x 其實這只是傳遞乙個思想而已,當兩者的lis都一樣時取最小值...

最長上公升子串行 nlogn

fi 表示i長度的上公升子串行的最小末尾元素值 用貪心的辦法,每次訪問乙個小於當前末尾值的元素,就往前二分地找乙個可以替換的位置 include include include include using namespace std define debug x cerr x x endl cons...

最長上公升子串行nlogn演算法

這題目是經典的dp題目,也可叫作lis longest increasing subsequence 最長上公升子串行 或者 最長不下降子串行。很基礎的題目,有兩種演算法,複雜度分別為o n logn 和o n 2 a.o n 2 演算法分析如下 a 1 a n 存的都是輸入的數 1 對於a n 來...