题目:hdu1160
题意:一群老鼠,每个老鼠有两个参数:重量和速度。寻找重量递增且速度递减的最长的子序列,输出该序列的坐标顺序。
解答:先排序,然后最长上升子序列。注意:排序后坐标会改变,因此,应当在结构体中引入一个新的变量index,保存它的原始位置。保存路径:记录比当前位置小的上一个位置的左边即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1000 + 10;
int t[MAXN];//保存路径的数组
int dp[MAXN];//dp[i]表示到第i个位置最长的子序列长度
struct M
{
int a,b,index;
};
bool cmp(M x,M y)
{
if(x.b == y.b)
return x.a < x.b;
return x.b > y.b;
}
M m[MAXN];
int main()
{
int len = 1;
while(scanf("%d %d",&m[len].a,&m[len].b)!=EOF)
{
m[len].index = len;
len++;
}
sort(m+1,m+len,cmp);
memset(dp,0,sizeof(dp));
dp[1] = 1;
memset(t,0,sizeof(t));
for(int i = 2;i < len;i++){
for(int j = 1;j < i;j++)
if(m[j].a < m[i].a && m[j].b != m[i].b)
{
if(dp[j] + 1 > dp[i])
{
dp[i] = dp[j] + 1;
t[m[i].index] = m[j].index;
}
}
dp[i] = max(1,dp[i]);
}
int ans = 0;
int loc = 0;
for(int i = 1;i < len;i++)
if(dp[i] > ans)
{
ans = dp[i];
loc = m[i].index;
}
printf("%d",ans);
int tmp[MAXN];
int cnt = 0;
tmp[0] = loc;
while(t[loc] != 0)
{
loc = t[loc];
tmp[++cnt] = loc;
}
for(int i = cnt;i >= 0;i--)
printf("\n%d",tmp[i]);
return 0;
}