题意:
输入中每行有两个正整数,分别表示老鼠的体重和速度,范围均在1到10000之间,输入数据最多有1000只老鼠。我们是要在原来的老鼠序列中,找到一个最长的子序列,使得这个子序列中老鼠的体重在严格增加,速度却在严格降低。
思路:
按照体重排序后,对速度跑一个最长上升子序列,dp形式的,方便记录路径,这里的记录路径和链式前向星原理比较像,在dp时记录最后更新这个节点的前一个节点的序号,dp完后从后往前找整个链就可以了。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct node{
int fat,speed,i;
bool operator < (const node &a){
if(fat==a.fat)return speed>a.speed;
else return fat<a.fat;
}
}s[10010];int dp[10010],pre[10010];
//struct node2{
// int sss,idx;
//}vis[10010];
int main(){
int a,b;int flag=0;
while(cin>>s[flag].fat>>s[flag].speed){
s[flag].i=flag+1;
flag++;
}
sort(s,s+flag);
// for(int i=0;i<flag;i++){
// cout<<s[i].fat<<" "<<s[i].speed<<endl;
// }
int fff=0,ans=0;
// memset(pre,-1,sizeof(pre));
for(int i=1;i<flag;i++){
dp[i]=1;
for(int j=0;j<i;j++){
if(s[i].speed<s[j].speed&&s[i].fat>s[j].fat){
if(dp[j]+1>dp[i]){
dp[i]=dp[j]+1;
pre[i]=j;
}
}
}
}
int now=0,be;
for(int i=0;i<flag;i++){
if(dp[i]>now){
now=dp[i];
be=i;
}
}
cout<<dp[be]<<endl;
int cnt=0;int num[10010];
for(int i=be;i!=0;i=pre[i])
num[cnt++]=s[i].i;
for(int i=cnt-1;i>=0;i--){
cout<<num[i]<<endl;
}
}