题意
给出w和v属性,求w递增和v递减的最长子序列,并输出路径。
思路
先按照一个属性排序,在此基础上写一个dp转移,然后记录路径的时候利用pre思想,记录他的前驱。
最后找答案的时候不断求pre得到答案。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 60000+66
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define mod 1000000007
#define INF 0x3f3f3f3f
struct node
{
int pos;
int w;
int v;
} a[maxn];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int dp[maxn];
int pre[maxn];
int main()
{
int x,y;
int n=0;
while(cin>>x>>y)
{
a[++n].pos=n;
a[n].w=x;
a[n].v=y;
}
sort(a+1,a+n+1,cmp);
rep(i,1,n)dp[i]=1;
for(int i=1; i<=n; i++)
{
for(int j=1; j<i; j++)
{
if(a[i].v<a[j].v&&a[i].w>a[j].w)
{
if(dp[i]<dp[j]+1)
{
pre[i]=j;//记录前面是谁
dp[i]=max(dp[i],dp[j]+1);
}
}
}
}
int ans=1;
int st=1;
rep(i,1,n)
{
if(dp[i]>ans)
{
st=i;
ans=dp[i];
}
}
cout<<ans<<endl;
stack<int>s;
while(st)
{
s.push(st);
st=pre[st];
}
while(!s.empty())
{
cout<<a[s.top()].pos<<endl;
s.pop();
}
return 0;
}