题目链接:点击查看
题目大意:给出许多二元组(W,S),最后要求输出最长的满足W严格递增,S严格递减的子序列长度,以及方案,输出任意一种即可
题目分析:看起来像二维偏序,其实对任意一维排序后求最长不下降子序列或最长不上升子序列即可,模板题,增加了个路径输出,在更新的时候保存一下即可,有点忘了板子了,贴一个一个月之前写的代码回顾回顾:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<sstream>
#include<cmath>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int N=1e3+100;
struct Node
{
int w,s;
int pos;
}a[N];
bool cmp(Node a,Node b)
{
if(a.s==b.s)
return a.w<b.w;
return a.s>b.s;
}
int d[N];
int c[N];
int main()
{
// freopen("input.txt","r",stdin);
int x,y;
int cnt=1;
while(scanf("%d%d",&x,&y)!=EOF)
{
a[cnt].w=x;
a[cnt].pos=cnt;
a[cnt++].s=y;
}
sort(a+1,a+1+cnt,cmp);
int len=1;
memset(d,0,sizeof(d));
d[1]=a[1].w;
c[1]=1;
for(int i=2;i<cnt;i++)
{
if(a[i].w>d[len])
{
d[++len]=a[i].w;
c[i]=len;
}
else
{
int j=upper_bound(d+1,d+1+len,a[i].w)-d;
d[j]=a[i].w;
c[i]=j;
}
}
cout<<len<<endl;
int j=len;
stack<int>ss;
for(int i=cnt-1;i>=1;i--)
{
if(c[i]==j)
{
ss.push(a[i].pos);
j--;
}
}
while(!ss.empty())
{
cout<<ss.top()<<endl;
ss.pop();
}
return 0;
}