示例 P1020 导弹拦截 用到了求最长下降子序列和最长上升子序列 ,还用到了 \(Dilworth 定理\) 证明第二问是最长上升子序列。
若 \(n=0\),则需要特判。 # 最长上升子序列
目前我笔记有三种写法,第一种即可。 推荐 1
1 |
|
推荐 2 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using namespace std;
vector<int> nums;
vector<int> vec;
int main()
{
int x;
cin >> x;
while(x--)
{
int y;
cin >> y;
nums.emplace_back(y);
}
int n = nums.size();
for (int i = 0; i < n; i++)
{
int p = lower_bound(vec.begin(), vec.end(), nums[i]) - vec.begin(); //二分查找,返回大于等于nums[i]的第一个位置
if (p == vec.size())
vec.push_back(nums[i]);
else
vec[p] = nums[i];
}
cout<< vec.size();
}
推荐 3 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using namespace std;
vector<int> d;
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
int t;
cin >> t;
auto it = lower_bound(d.begin(), d.end(), t);
if (it != d.end())
*it = t;
else
d.push_back(t);
}
cout << d.size() << endl;
}
最长下降子序列
和上面的代码思路一模一样,稍改
1 |
|