https://vjudge.net/contest/430905#problem/C
给出猫的体重和对应的速度,要求是得到一个体重上升的子序列的同时,速度必须是严格下降的序列。
请输出最长的这样的子序列,并且输出这些猫的原本的序号。
我们需要一个结构体来记录猫的体重,速度和序号。按照速度下降来排序,最后转化成了求体重的最长上升子序列。
这答案多种,取任意一个即可。
#include<iostream>
#include<algorithm>
using namespace std;
struct mouse
{
int a,b,c;
} m[1005];
bool cmp(mouse x,mouse y)
{
if(x.b!=y.b) return x.b>y.b;
else return x.a<y.a;
}
int main()
{
int n=0;
int x,y;
while(cin >> x>>y)
{
n++;
m[n].a=x;
m[n].b=y;
m[n].c=n;
}
sort(m+1,m+1+n,cmp);
int d[1005]={0},maxx=0,rr[1005];
for(int i=2; i<=n; i++)//这是最长上升子序列的套路
{
for(int j=i-1; j>=1; j--)
{
if(m[i].a>m[j].a&&m[i].b<m[j].b)
//限制体重的同时,别忘了速度是严格下降的
{
d[i]=max(d[j]+1,d[i]);//状态转移方程,用d标记了当前体重的最大长度
maxx=max(d[i],maxx);//一直更新子序列的最大长度
}
}
}
cout << maxx+1 << endl;
int r=maxx,minn=100000;
x=0;
for(int i=n;i>=1,r>=0;i--)
//这一步必须反向遍历,后面的大的值一定是由前面小值得到的,而前面小值的后面不一定有大值
//这里的大是指子序列长度
{
if(d[i]==r&&m[i].a<minn)
{
rr[r]=m[i].c;//标记序号
minn=m[i].a;//更新当前长度最大值的体重的最大值
r--;
}
}
for(int i=0;i<=maxx;i++)
{
cout << rr[i]<< endl;
}
return 0;
}