POJ2533 最長遞增子序列

本題是求一個序列的最長遞增子序列,採用動態規劃,遞推公式爲:
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,所以一定要把整個過程理解清楚,不要囫圇吞棗,也不要在同一個地方摔倒了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章