题目大意:
求双元素(LIS)
思路:
将数据以其中以一个元素为关键字进行排序,再求单元素(LIS)即可。
设(f[i])为前(i)个元素中的(LIS)长度,易得(dp)方程为
[dp[i] = max(1, dp[j] + 1) (j = 0, 1, … , i - 1, w_j < w_i, h_j < h_i)
]
用(pre)数组输出链的序号,(pre[i])表示以元素(i)结尾的序列在元素(i)之前元素的序号。
Code:
#include <bits/stdc++.h>
using namespace std;
const int N = 5010;
struct Node
{
int w, h, id;
bool operator<(const Node& t) const {return w < t.w; }
}env[N];
int pre[N], n, w, h, ans = 1, f[N], cnt, ptr = 1;
void print(int p) {
if (p == -1) return;
print(pre[p]);
cout << env[p].id << " ";
}
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> w >> h;
for (int i = 1; i <= n; i++) {
int a, b; cin >> a >> b;
if (a > w && b > h) {
env[++cnt].w = a;
env[cnt].h = b;
env[cnt].id = i;
}
}
if (cnt) {
sort(env + 1, env + 1 + cnt);
for (int i = 0; i <= cnt + 1; i++) f[i] = 1, pre[i] = -1;
for (int i = 2; i <= cnt; i++) {
for (int j = 1; j < i; j++) {
if (env[j].w < env[i].w && env[j].h < env[i].h && f[j] + 1 > f[i]) {
f[i] = f[j] + 1;
pre[i] = j;
}
}
if (ans < f[i]) ans = f[i], ptr = i; //在f数组中寻找最大值,同时更新头指针
}
cout << ans << endl;
print(ptr);
cout << endl;
} else
cout << 0 << endl;
return 0;
}