LIS(最长上升子序列两种算法模板)DP模板,并且输出序列

来源:互联网 发布:淘宝前100名半价怎么抢 编辑:程序博客网 时间:2024/04/30 04:11

【最长上升子序列的各种模板】

有两种复杂度的算法,n^2的算法可以算出长度的同时记录每个选择的点,而nlogn的算法只能算出长度

【n^2的模板】

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define MAXN 5010int a[MAXN], dp[MAXN], f[MAXN];//dp[i]表示以a[i]为终点的最长上升子序列的长度,f[i]记录最优解父亲节点void pt(int s)//输出一种最长上升子序列{    if (-1 == s)        return;    pt(f[s]);    printf ("%d ", a[s]);}int main (){    #ifdef SHY        freopen("e:\\1.txt", "r", stdin);    #endif    int n;    scanf ("%d%*c", &n);    memset(f,-1,sizeof(f));    dp[0] = 1;//把只有一个数的序列最长子序列长度设置为1,边界处理    for (int i = 0; i < n; i++)        scanf ("%d%*c", &a[i]);    int ans = 1, ss;    for (int i = 1; i < n; i++)    {        dp[i] = 1;        for (int j = 0; j < i; j++)//枚举终点不算的时候左边最长的子序列长度            if (a[j] < a[i] && dp[j]+1 > dp[i])                dp[i] = dp[j]+1, f[i] = j;        if (ans < dp[i])//因为最后一个点不一定是最长子序列的终点,所以要去所有点为终点的最长的那一个            ans = dp[i], ss = i;    }    printf ("%d\n", ans);    pt(ss);    return 0;}

【nlogn模板HDU1025】

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define MAXN 500010int len, d[MAXN], a[MAXN];//d[]是一个单调递增队列,用来贪心的记录当前下标的长度下,可以得到的一个末尾数字最小的子序列//d[]中的每一个数在更新过程中是单调不上升的int main (){    #ifdef SHY        freopen("e:\\1.txt", "r", stdin);    #endif    int n, count = 0;    while(~scanf ("%d%*c", &n))    {        int s,v;        len = 0;//当前可以得到的最长的上升子序列的长度        for(int i = 0; i < n; i++)        {            scanf ("%d %d%*c", &s, &v);            a[s] = v;        }        for (int i = 1; i <= n; i++)        {            if (a[i] > d[len])//如果当前值大于队列中的最大值的话把它放在最后,并且最大长度加一                d[++len] = a[i];            else            {                int l = 1, r = len, mid;                while(l <= r)//二分查找d[j]<a[i]的最大的j,并d[j+1] = a[i]                {                    mid = (l+r) >> 1;                    if (a[i] <= d[mid])                        r = mid-1;                    else                        l = mid+1;                }                d[l] = a[i];            }        }        printf ("Case %d:\n", ++count);        if (1 == len)            printf ("My king, at most %d road can be built.\n\n", len);        else            printf ("My king, at most %d roads can be built.\n\n", len);    }    return 0;}



 

0 0
原创粉丝点击