動態規劃求最長遞增序列

 參考:https://blog.csdn.net/s448312891/article/details/80318746

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;
/**
 * @brief getdp:返回遞增序列的最大值
 * @param arr
 * @return
 * dp[i]:表示在以arr[i]這個數據結尾的情況下,arr[0...i]中的最大遞增序列長度
 *       對第一個數來arr[0]來說,令dp[0]=1
 */
vector<int>  getdp(vector<int> &arr)
{
     vector<int>  dp(arr.size(),0);
     for(int i=0;i<arr.size();i++){
         dp[i]=1;
         //在子序列中去確定一個遞增序列
         for(int j=0;j<i;j++){
             if(arr[j]<arr[i]){
                 dp[i]=max(dp[j]+1,dp[i]);
             }
         }
     }
   return dp;
}

/**
 * @brief generateLIS
 * @param arr
 * @param dp
 * @return
 * test: 2 1 5 3 6 4 8 9 7
 */
vector<int> generateLIS(vector<int> arr, vector<int> &dp)
{
    int len=0;
    int index=0; //返回序列的下標
/*尋最長遞增子序列末尾的位置和值*/
    for(int i=0;i<dp.size();i++){
        if(dp[i]>len){
            len=dp[i]; //這句話的作用就是找出最大值dp(dp代表的時候最大長度)
            index=i;   //找出最大值時候的下對應最大時候的下標值
        }
    }
    vector<int> list(len,0);  //

    list[--len]=arr[index];
    //遍歷輸出
    for(int i=index;i>=0;i--){
        //這裏是從後往前找子序列
        if(arr[i]<arr[index]&&dp[i]==dp[index]-1){
            list[--len]=arr[i];
            index=i;
        }
    }
    return list;

}
int main()
{
    vector<int>  arr;
    int temp;
    while(cin>>temp){
        arr.push_back(temp);
    }
    vector<int> dp=getdp(arr);
    vector<int>::iterator it;
    for(it=dp.begin();it!=dp.end();it++){
        cout<< *it<<" ";
    }
    cout<<endl;
    vector<int>  list=generateLIS(arr,dp);
    for(int i=0;i<list.size();i++){
        cout<<list[i]<<" ";
    }
    return 0;
}

 

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