题意
中文题面
题解
[线性DP--LIS模型]
分析:
找最长上升子序列,因为找到它之后,每一个其中的数是一定要指定为起点的
Code
#include <iostream>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define read(a) scanf("%d", &a)
#define readl(a) scanf("%lld", &a)
#define readf(a) scanf("%lf", &a)
#define reads(a) scanf("%s", a)
#define pb push_back
#define _rand mt19937 RAND(time(0))
#define mem(a) memset(a, 0, sizeof(a))
#define Buff ios::sync_with_stdio(false)
const int INF = 1e9 + 7;
const int N = 1e3 + 7;
int dp[N], pre[N];
struct node
{
int wight, speed, id;
node(int wight = 0, int speed = 0, int id = 0):wight(wight), speed(speed), id(id){}
bool operator < (const node & A)const
{
return wight > A.wight && speed < A.speed;
}
}s[N];
bool cmp(const node &A, const node &B)
{
return (A.wight > B.wight || A.wight == B.wight && A.speed < B.speed);
}
int Case = 0;
void print(int u)
{
if(u == pre[u])
{
printf("%d\n", s[u].id);
return ;
}
printf("%d\n", s[u].id);
print(pre[u]);
}
signed main()
{
int n = 0, a, b;
while(~scanf("%d%d", &a, &b))
s[++n] = node(a, b, n);
sort(s + 1, s + n + 1, cmp);
int id = 0; dp[id] = 0;
for(int i = 1; i <= n; i++)
{
dp[i] = 1; pre[i] = i;
for(int j = 1; j < i; j++)
if(s[j] < s[i] && dp[j] + 1 > dp[i])
{
dp[i] = dp[j] + 1;
pre[i] = j;
}
if(dp[id] < dp[i]) id = i;
}
printf("%d\n", dp[id]);
print(id);
}