最长上升子序列的变化

来源:互联网 发布:淘宝查询信誉网站 编辑:程序博客网 时间:2024/04/30 06:24

题目: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;}


0 0