POJ2533 最长递增子序列

来源:互联网 发布:mac mp3转m4r 编辑:程序博客网 时间:2024/06/18 05:08

本题是求一个序列的最长递增子序列,采用动态规划,递推公式为:
f(j) = max{ f(i)+1} ,其中1<=i,并且a(j)>a(i)
其中f(j)表示选择上a(j)时,串长为j的最长递增子序列。注意不是单纯的串长为j的最长递增子序列。
值得注意的是:

1.f(j)要初始化为1,因为单个字符的最长递增子序列的长就是他自己,长度为1。
2.在每次求max{f(i)+1},不能写成f(j)=max(f(j-1),max(f(i)+1,f(j)),因为存在这样的序列,比如{1 7 3 5 9 4 8},如果每次取当前值与前一个值得最大值时,考虑f(6)=f(5)=4,在计算f(7)时,发现a(7)>a(6),于是f(7)=f(6)+1=5,计算结果错误。这里再次强调,f(j)表示的是选上串字符j时的最长递增子序列,所以f(6)=3。也因为如此,在输出结果的时候需要求说有f数组中的最大值。

/** f(j)=max{f(i)+1},1<=i<j&&a[i]<a[j]*/#include<iostream>#include<vector>using namespace std;int main(){    int n;    while(cin>>n)    {        vector<int> a(n+1);        for(int i=1;i<=n;i++)cin>>a[i];        vector<int> f(n+1,1);//一定初始化为1         for(int j=1;j<=n;j++)            for(int i=1;i<j;i++)                if(a[j]>a[i])f[j]=max(f[j],f[i]+1);         int maxl=f[n];        for(int i=1;i<=n;i++) maxl=max(maxl,f[i]);        cout<<maxl<<endl;    }    return 0; }

这段有效长度不足20行的代码,而且是做过的练习,我在考试中作了整整3个小时!!!最后发现原因就是没有把初值设为1,所以一定要把整个过程理解清楚,不要囫囵吞枣,也不要在同一个地方摔倒了。

0 0
原创粉丝点击