【编程题目】求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5, 4,3,2}

47.创新工场(算法):
求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,
4,3,2}

 

思路:动态规划

从最后一个数字开始,计算以当前数字其实的序列的最长递减子序列。 每次找最长子序列,都扫描它之前求得的子序列中最长,且第一个数字比当前数字小的。

如: 第一个数字 2, 最大长度 1, 下一个数字是 第 7 个

      第二个数字 3,  最大长度 2, 下一个数字是 第 7 个

      第三个数字 4,  最大长度 3, 下一个数字是 第 6 个

      第四个数字 5,  最大长度 4, 下一个数字是 第 5 个

      第五个数字 2,  最大长度 1, 下一个数字是 第 3 个

      第六个数字 3,  最大长度 2, 下一个数字是 第 3 个

      第七个数字 4,  最大长度 3, 下一个数字是 第 2 个

      第八个数字 9,  最大长度 5, 下一个数字是 第 4 个

这样就可以找到最大长度,并根据存储的下一个数字找到最长递减序列。

/*
47.创新工场(算法):
求一个数组的最长递减子序列  比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,
4,3,2}
*/

#include <stdio.h>
#include <stdlib.h>

int maxLength(int * a, int len)
{
    int * pos = (int *)malloc(2 * len * sizeof(int));

    //找到以每一个元素起始的最长递减子序列
    pos[2 * (len - 1)] = 1; //以最后一个数字为首的最长递减子序列长度
    pos[2 * len - 1] = len - 1; //最后一个数的下一个数字
    for (int i = len - 2; i >= 0; i--)
    {
        int maxlen = 0;
        int nextpos = i;
        for (int j = i + 1; j < len; j++)
        {
            if (a[j] < a[i])
            {
                if (pos[2 * j] > maxlen)
                {
                    maxlen = pos[2 *j];
                    nextpos = j;
                }
            }
        }
        pos[2 * i] = maxlen + 1; //以a[i]为首的最长递减子序列长度
        pos[2 * i + 1] = nextpos; //a[i]的下一个数字
    }

    //找到最长的递减序列
    int maxstart = 0;
    int max = 0;
    for (int i = 0; i < len; i++)
    {
        if (pos[2 * i] > max)
        {
            max = pos[2 * i];
            maxstart = i;
        }
    }

    //打印最长递减子序列
    printf("最长递减子序列为:");

    int next = maxstart;
    do
    {
        printf("%d ", a[next]);
        next = pos[2 * next + 1];
    }while(next != pos[2 * next + 1]);
    printf("%d\n", a[next]);

    free(pos);
    return max; //返回最大长度
}

int main()
{
    int a[8] = {9,4,3,2,5,4,3,2};
    int len = maxLength(a,8);
    return 0;
}

 

发现我又有一个地方傻×了,其实可以不用存下一个数字的位置的,直接查找最大长度少一的数字并打印就可以了。

如下:http://blog.csdn.net/wumuzi520/article/details/7378306

#include <iostream>
#include <cstring>
using namespace std;

int Fun(int aIn[],int pTable[],int nLen)
{
    int nMaxLen = 0;
    for(int i = nLen-1; i >= 0; --i) {
        int nMax = 0;
        for(int j = i+1; j < nLen; ++j) {
            if(aIn[j] < aIn[i]) {
                nMax = nMax < pTable[j] ? pTable[j] : nMax;
            }
        }
        pTable[i] = 1+nMax;
        nMaxLen = nMaxLen<pTable[i] ? pTable[i] : nMaxLen;
    }

    return nMaxLen;
}

void PrintMaxSubsequence(int aIn[], int pTable[], int nMaxLen, int nLen)   //!!!!!!!!!!
{
    for(int i = 0,j=0; i < nLen; ++i) {  
        if(pTable[i] == nMaxLen){
            cout << aIn[i] << " ";
            nMaxLen--;
        }
    }
    cout << endl;
}

 

posted @ 2014-08-13 15:01  匡子语  阅读(2560)  评论(0编辑  收藏  举报