一、题目描述
https://zoj.pintia.cn/problem-sets/91827364500/problems/91827364607
Sample Input
6008 1300
6000 2100
500 2000
1000 4000
1100 3000
6000 2000
8000 1400
6000 1200
2000 1900
Output for Sample Input
4
4
5
9
7
二、思路
题目总结就是求,在老鼠体重递增,速度递减最长的子集。最后输出的最长子集的长度和老鼠编号。
1、首先定义结构体 其中存储体重,速度,由于最终需要输出最长序列的编号,所有我们也需要存储老鼠编号。
2、对体重进行升序,然后对速度求最长单调递减子序列,求的时候注意要保存下标值。
path[]:保存的是子序列的前驱。
3、递归输出老鼠编号
三、代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct mouse{
//老鼠编号
int id;
int weight;
int speed;
void set_mouse(int i,int w,int s){
id=i;
weight=w;
speed=s;
}
}m[1005];
//按体重升序排序
bool cmp(mouse m1,mouse m2){
return m1.weight<m2.weight;
}
void output(int path[],int pos){
if(pos==0) return;
output(path,path[pos]);
printf("%d\n",m[pos].id);
}
int main(){
int n=0,w,s;
while(scanf("%d%d",&w,&s)!=EOF){
n++;
m[n].set_mouse(n,w,s);
}
sort(m+1,m+n+1,cmp);
//然后在速度中找最长单调递减子序列
int b[1005];
b[1]=1;
//记录b[1:i]的最大值
int max0=0;
//path数组:因为最后输出编号 我们使用辅助数组记录子序列的前驱
int path[1005]={0};
int pos;
for(int i=2;i<=n;i++){
//记录b[i]的最大值
int k=0;
for(int j=1;j<i;j++){
if(m[i].speed<m[j].speed&&m[i].weight>m[j].weight&&b[j]>k){
k=b[j];
//记录前驱
path[i]=j;
}
}
b[i]=k+1;
//找最大长度和下标
if(max0<b[i]){
max0=b[i];
pos=i;
}
}
printf("%d\n",max0);
//输出
output(path,pos);
return 0;
}
本文介绍了一道经典的最长递减排列问题,并提供了一个具体的实现方案。通过定义结构体存储老鼠的编号、体重和速度,利用C++实现排序和最长递减排列的计算,最终输出最长子序列的长度及对应的老鼠编号。
289





