動態規劃——最長單調遞增子序列
阿新 • • 發佈:2018-12-12
題目描述
用動態規劃設計一個演算法,要求找出由n個整陣列成的序列的最長單調遞增子序列的個數(假設所有的元素都不相同)。
輸入
第一行輸入一個整數,表示有n個整數。
第二行輸入n個整數。
輸出
第三行輸出最長單調遞增子序列的個數。
樣例輸入
6 1 3 2 5 4 0
樣例輸出
3
思路:還是動態規劃的思想,定義一個數組longest[MAX],longest[a]表示在前a項中最長的子序列長度,一開始陣列元素全部初始化為1。然後外面一層迴圈從第二元素開始迴圈(因為longest[0]肯定是1),一直到最後一個元素,第二個迴圈從第一個元素開始迴圈到外迴圈的前一個元素,只要外面迴圈代表的這個元素,比裡面迴圈代表的元素大,那麼就判斷外迴圈的longest值(longest[i])是否小於內迴圈的longest+1的值(longest[j]+1) 因為外迴圈每次迴圈都能得到一個最優的longest 所以到最後在longest裡面找到的最大的值 即為整個陣列中最長遞增子序列的長度。動態轉移方程即為:
if(arr[i]>arr[j]){
longest[i]=max(longest[i],longest[j]+1);
}
AC程式碼:
#include <iostream> #include <string.h> using namespace std; const int MAX=1000; int find(int arr[],int n); int main(void){ int n; int arr[MAX]; cin>>n; for(int i=0;i<n;i++){ cin>>arr[i]; } int max=find(arr,n);//尋找最優值 cout<<max<<endl; return 0; } int find(int arr[],int n){ int longest[MAX]; fill(longest,longest+n,1); for (int j=1; j<n; j++) { for (int i=0; i<j; i++) { if (arr[j]>arr[i] && longest[j]<longest[i]+1){ //注意longest[j]<longest[i]+1這個條件,不能省略。因為必須保證是最優值。 longest[j] = longest[i] + 1; //計算以arr[j]結尾的序列的最長遞增子序列長度 } } } int max=0; for(int i=0;i<n;i++){//尋找Longest最優數組裡面的最大值 即為答案 if(max<longest[i]){ max=longest[i]; } } return max; }