题意:很多肥老鼠认为,长的越肥,奔跑速度就越快,为了反驳这个观点,你现在需要对老鼠的体重和速度进行研究,你要在老鼠序列中找出一个子序列,使得老鼠的体重在增加,但是速度却在减慢
Input
输入以eof结束。输入中每行有两个正整数,分别表示老鼠的体重和速度,范围均在1到10000之间,输入数据最多有1000只老鼠。某些老鼠可能有相同的体重,某些老鼠可能有相同的速度,某些老鼠可能体重和速度都相同。
Output
我们是要在原来的老鼠序列中,找到一个最长的子序列,使得这个子序列中老鼠的体重在严格增加,速度却在严格降低。
首先输出满足条件的最长的子序列的长度。
其次,输出一个最长子序列的方案,要求输出每个老鼠在输入时候的编号,每个编号占一行,任意一种正确的方法都会被判正确。
思路:其实可以发现就是一个LIS,但是需要先排个序。和LIS不同的地方就是判断升序的条件变了,需要体重升序且速度降序,并且过程中记录一下路径,记录下每个点是由哪个点转移过来的,用pos记录下终点,递归打印路径即可。
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2005;
const int INF = 0x3f3f3f3f;
int n, dp[MAXN], path[MAXN];
struct Mouse
{
int w, s, id;
bool operator < (const Mouse& that) const
{
if (w != that.w) return w < that.w;
return s < that.s;
}
}a[MAXN];
void putout(int x)//打印路径
{
if (x == -1) return ;
putout(path[x]);
printf("%d\n", a[x].id);
}
int main()
{
while (~scanf("%d%d", &a[n].w, &a[n].s))
{
a[n].id = n+1;
n++;
}
sort(a, a+n);
memset(path, -1, sizeof(path));
int len = 0, pos = 0;//pos记录终点位置
for (int i = 0; i < n; i++)
{
dp[i] = 1;
for (int j = 0; j < n; j++)
{
if (a[j].w < a[i].w && a[j].s > a[i].s && dp[i] < dp[j]+1)
{
dp[i] = dp[j]+1;
path[i] = j;
}
}
if (len < dp[i])
{
len = dp[i];
pos = i;
}
}
printf("%d\n", len);
putout(pos);
return 0;
}
/*
6008 1300
6000 2100
500 2000
1000 4000
1100 3000
6000 2000
8000 1400
6000 1200
2000 1900
*/