昨天刚学完动态规划,今天用这道题练练手
思路在于dp[i]表示的是以第i个为结尾的子序列的长度,注意是以第i个为结尾,而不是在i之前任意子序列的最长长度。
很容易推算出来dp[i]=max(dp[i],dp[j]+1),这里需要满足的前置要求为p[j]<p[i],也就是第j个数字要小于新加入的数字才能够执行(原因就是在于上面说的,以第i个为结尾)。
这里的输出方法,首先找到最大的dp[i],然后通过倒叙的方法,依次找他的前一个子序列,判定的方法是找到的数要小于上一个数,而且对应的dp的值刚好是上一个数对应的dp值-1,然后进行输出就好。
代码如下:
#include <iostream>
#include<algorithm>
#include<vector>
using namespace std;
int dp[1001];
int M;
int main()
{
cin>>M;
int *p=new int[M];
for(int i=0;i<M;i++)
{
cin>>p[i];
dp[i]=1;
}
for(int i=0;i<M;i++)
{
for(int j=0;j<i;j++)
{
if(p[j]<p[i])
{
dp[i]=max(dp[i],dp[j]+1);
}
}
}
int index=0;
int max=0;
for(int i=0;i<M;i++)
{
if(dp[i]>max)
{
max=dp[i];
index=i;
}
}
vector<int>ans;
int j=index;
ans.push_back(p[index]);
for(int i=index-1;i>=0;i--)
{
if(dp[i]+1==dp[j]&&p[i]<p[j])
{
ans.push_back(p[i]);
j=i;
}
}
for(int i=ans.size()-1;i>=0;i--)
{
cout<<ans[i]<<" ";
}
}
若有错误请多多指教。