题解 | #拦截导弹#
拦截导弹
https://www.nowcoder.com/practice/218f3db1f66d465bbf9578625aa90785
根据 Dilworth 定理(一个有序集合的最小链划分数等于最大反链的大小),我们可以知道:
- 最小链划分数:把导弹高度序列划分成若干条递减序列所需的最小数量。
- 最大反链的大小:一个最长上升子序列的长度(因为两个元素不可比较的意思就是:它们可以构成一个递增的关系)
可以将序列化分为若干个递减子序列 =》 通过找到最长上升子序列的数量来求解
#include <algorithm>
#include <cstring>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
const int N = 1010;
int a[N];
int f[N];
int maxLength(int n) {
int res = 0;
for (int i = 0; i < n; i ++) {
f[i] = 1;
for (int j = 0; j < i; j ++) {
if (a[i] <= a[j]) f[i] = max(f[j] + 1, f[i]);
}
res = max(res, f[i]);
}
return res;
}
int minSystem(int n) {
int res = 0;
for (int i = 0; i < n; i ++) {
f[i] = 1;
for (int j = 0; j < i; j ++) {
//Dilworth
if (a[i] > a[j]) {
f[i] = max(f[i], f[j] + 1);
}
}
res = max(f[i], res);
}
return res;
}
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i ++) cin >> a[i];
cout << maxLength(n) << endl;
memset(f, 0, sizeof f);
cout << minSystem(n) << endl;
return 0;
}
途虎成长空间 159人发布