【最长上升子序列 && 输出路径】HDU

来源:互联网 发布:淘宝福兴隆珠宝是假的 编辑:程序博客网 时间:2024/05/22 17:03

Problem Description

给你若干个,老鼠的数据,数据里面有两个,一个是体重,一个是速度,让你求出最长的子序列,按照体重不断的减少,速度不断的增加。

思路:

我们按照速度从大到小排序,就变成了求体重最长上升子序列了。状态转移方程dp[i] = max{dp[0]…..dp[i - 1]}(满足上升条件) + 1.

#include<bits/stdc++.h>using namespace std;#define inf 0x3f3f3f3fstruct node{    int w, v, num;    bool operator < (const node &b) const {        if(v == b.v) return w < b.w;        else return v > b.v;    }};node a[1505];int dp[1505], Pre[1505];void print(int u){    if(!u) return;    print(Pre[u]);    printf("%d\n", a[u].num);}int main(){    memset(Pre, 0, sizeof(Pre));    int w, v, n = 1, jj;    while(~scanf("%d %d", &w, &v))    {        a[n].num = n;        a[n].w = w;        a[n++].v = v;    }    sort(a + 1, a + n + 1);//按照速度从大到小排序,如果速度相同体重从小到大排序    int Max, u, ans = 0;    for(int i = 1; i <= n; i++)//求最长上升子序列 && 记录路径    {        dp[i] = 1;        Max = 0;        for(int j = i - 1; j >= 1; j--)//1 - (i - 1)找最大的dp[]满足上升条件        {            if(a[i].w > a[j].w)//满足条件            {                if(Max < dp[j]){                     u = j;                    Max = dp[j];                }            }        }        if(Max)//找到了,更新,顺便记录路径        {            if(dp[u] + 1 > dp[i]){            dp[i] = dp[u] + 1;            Pre[i] = u;            }        }        ans = max(ans, dp[i]);    }    printf("%d\n", ans);    for(jj = 1; jj <= n; jj++)//输出路径    {        if(dp[jj] == ans)        {            print(jj);            break;        }    }    return 0;}
原创粉丝点击