最长上升子序列

来源:互联网 发布:java架构师薪水高吗 编辑:程序博客网 时间:2024/05/29 16:55

nyoj 17 http://acm.nyist.net/JudgeOnline/problem.php?pid=17&rec=rec
动态规划的思想

#include<stdio.h>#include<iostream>#include<string.h>#include<algorithm>using namespace std;int dp[10000+10];char a[10000+10];int t;int res;int  solve(char *a,int n){   // 参考挑战程序设计入门经典;       res = 0;        for(int i = 0; i < n; ++i){            dp[i] = 1;            for(int j = 0; j < i; ++j){                if(a[j] < a[i]){                    dp[i] = max(dp[i], dp[j]+1);                }            }            res = max(res,dp[i]);        }     return res;    }    int main()    {        int len;        scanf("%d",&t);        for(int i = 0; i < t ;i++)        {            scanf("%s",a);            memset(dp,0,sizeof(dp));            len = strlen(a);            solve(a,len);            printf("%d\n",  solve(a,len));        }        return 0;    }
    状态转移dp[i] = max{ 1.dp[j] + 1 }; j<i;a[j]<a[i];      d[i]是以i结尾的最长上升子序列      与i之前的 每个a[j]<a[i]的 j的位置的 最长上升子序列+1后 的值比较      int  solve(char *a,int n){   // 参考挑战程序设计入门经典;       res = 0;        for(int i = 0; i < n; ++i){            dp[i] = 1;            for(int j = 0; j < i; ++j){                if(a[j] < a[i]){                    dp[i] = max(dp[i], dp[j]+1);                }            }            res = max(res,dp[i]);        }     return res;    }    优化方法      //dp[i]表示长度为i+1的上升子序列的最末尾元素;      //找到第一个比dp末尾大的,代替      void solve() {          fill(dp, dp + n, INF);          for (int i = 0; i < n; i++) {              *lower_bound(dp, dp + n, a[i]) = a[i];//返回一个指针          }          printf("%d\n", *lower_bound(dp, dp + n, INF) - dp;      }      //函数lower_bound()返回一个 iterator 它指向在[first,last)标记的有序序列中可以插入value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个不小于value 的值。  
0 0
原创粉丝点击