这道题有点最长上升子序列的意思·····,只不过限制条件多了一个必须保证w[i]<w[i+1]&&s[i]>s[i+1],存路径的时候保存前驱节点就可以了。
#include<iostream>
#include<cstdio>#include<string.h>
#include<string>
#include<set>
#include<algorithm>
#include<cmath>
#include<stack>
#define ll __int64
#define MAX 1000009
using namespace std;
int dp[MAX];
int pre[MAX];
struct node
{
int w;
int s;
int num;
} op[MAX];
bool cmp(node A,node B)
{
if(A.w!=B.w)
return A.w<B.w;
else
return A.s>A.s;
}
int main()
{
int n,m;
int i,j;
int k = 0;
while(scanf("%d%d",&n,&m)!=EOF)
{
op[k].w = n;
op[k].s = m;
op[k].num = k + 1;
k++;
}
//cout<<k<<endl;
sort(op,op+k,cmp);
// for(i = 0; i<k; i++)
// {
// cout<<op[i].w<<" "<<op[i].s<<" "<<op[i].num<<endl;
// }
memset(dp,0,sizeof(dp));
dp[0] = 1;
for(i = 1; i<k; i++)
{
dp[i] = 1;
for(j = 0; j<i; j++)
{
if(op[i].w>op[j].w&&op[i].s<op[j].s&&dp[j]+1>dp[i])
{
dp[i] = dp[j] + 1;
pre[i] = j;
}
}
}
int _max = 0;
int flag = 0;
for(i = 0; i<k; i++)
{
if(_max<dp[i])
{
flag = i;
_max = dp[i];
}
}
cout<<_max<<endl;
stack<int>S;
while(flag)//这里不断找前驱节点然后存进stack里
{
S.push(flag);
flag = pre[flag];
}
while(!S.empty())
{
cout<<op[S.top()].num<<endl;
S.pop();
}
return 0;
}