codeforces 4D
题意:给定n和信封和一个w 和 h,要求以下的信封选取最多的,然后 wi 必须比 w 大并递增,hi 比 h 大也递增,问最多的信封数和哪些,按照顺序输出
题解:按照w递增排序后,求h的最长上升子序列并输出路径
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<stack>
#include<cstdlib>
#include<queue>
#include<set>
#include<string.h>
#include<vector>
#include<deque>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
#define eps 1e-4
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define ll long long
#define LL long long
const int MAXN = 1e5 + 5;
const int mod = 998244353;
struct node{
int w,h;
int id;
}a[MAXN];
bool cmp(node a,node b) {
if(a.w != b.w) return a.w < b.w;
return a.h < b.h;
}
int dp[MAXN];
int path[MAXN];
void print(int n) {
if(path[n] == -1) {
printf("%d ",a[n].id);
return ;
} else {
print(path[n]);
printf("%d ",a[n].id);
}
}
int main() {
int n, w, h;
cin >> n >> w >> h;
int pos = 0;
for(int i = 1; i <= n; i++) {
int w1,h1;
cin >> w1 >> h1;
if(w1 > w && h1 > h) {
a[pos].w = w1;
a[pos].h = h1;
a[pos].id = i;
pos++;
}
}
if(pos == 0)
{
cout << 0 << endl;
return 0;
}
sort(a, a + pos, cmp);
for(int i = 0; i < pos; i++) {
dp[i] = 1;
path[i] = i;
}
memset(path, -1, sizeof path);
int maxlen = 1,biao = 0;
for(int i = 0; i < pos; i++) {
for(int j = 0; j < i; j++) {
if(a[j].h < a[i].h && a[j].w < a[i].w && dp[i] < (dp[j] + 1)) {
dp[i] = dp[j] + 1;
if(dp[i] > maxlen) maxlen = dp[i];
path[i] = j;
}
}
}
int tmp,cmp = 0;
for(int i = 0; i < n; i++) {
if(dp[i] > cmp) {
cmp = dp[i];
tmp = i;
}
}
cout << maxlen << endl;
// debug(tmp);
print(tmp);
}