一、 二重循环解法:
暴力枚举 第
n
n
n位之前比 它小的 j
d
p
[
i
]
=
m
a
x
(
d
p
[
i
]
,
d
p
[
j
]
+
1
)
(
0
<
j
<
i
)
dp[i] = max(dp[i], dp[j] + 1) (0<j < i)
dp[i]=max(dp[i],dp[j]+1)(0<j<i)
#include<bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
const int N = 1010;
int a[N], dp[N];
int main()
{
ios::sync_with_stdio(0), cin.tie(0);
int n;
while (cin >> n)
{
for (int i = 1; i <= n; i++)
{
cin >> a[i];
dp[i] = 1;
}
for (int i = 2; i <= n; i++)
{
for (int j = 1; j < i; j++) //这里内层暴力循环
if (a[i] <= a[j])
dp[i] = max(dp[i], dp[j] + 1);
}
int ans = 0;
for (int i = 1; i <= n; i++)
ans = max(ans, dp[i]);
cout << ans << endl;
}
return 0;
}
二、二分的解法
简单的来说就是:线性扫描 序列,遇到比 “构造的序列”最后一个数大的就接上去,否则,用它替换前面第一个比它大的,
#include<bits/stdc++.h>
using namespace std;
const int MOD = 1000000007;
const int N = 1010;
//最长下降子序列 反着存就是最长上升子序列
int a[N], lis[N];
int main()
{
ios::sync_with_stdio(0), cin.tie(0);
int n;
while (cin >> n)
{
for (int i = n; i >= 1; i--)
cin >> a[i];
lis[1] = a[1];
int len = 1;
for (int i = 2; i <= n; i++)
{
if (a[i] >= lis[len])
lis[++len] = a[i];
else
{
int replace = upper_bound(lis + 1, lis + 1 + len, a[i]) - lis;
lis[replace] = a[i];
}
}
cout << len << endl;
}
return 0;
}