第1关:最长非降子序列(非连续)问题
任务描述
本关任务:掌握动态规划算法思想,并能利用动态规划算法思想解决最长非降子序列(非连续)问题:
由n个正整数组成的序列,从该序列中删除若干个整数,使得剩下的整数组成单调非降子序列,求最长的单调非降子序列并输出(测试数据保证有唯一解)。
编程要求
本关的编程任务是补全右侧代码片段main中Begin至End中间的代码,具体要求如下:
在main中,读取整数n以及n个整数序列,运用动态规划的算法思想编程求解出该序列的最长非降子序列,并输出(所有输出整数之间空格隔开,末尾换行)。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 101;
int main(int argc, const char * argv[]) {
// 请在这里补充代码,完成本关任务
/********* Begin *********/
int n;
int dp[maxn+5];
int s1[maxn+5];
int prin[maxn+5];
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&s1[i]);
}
int maxnum=1;
dp[n]=1;
for(int i=n-1;i>=1;i--){
int maxx=0;
for(int j=i+1;j<=n;j++){
if(s1[j]>=s1[i]&&dp[j]>maxx){
maxx=dp[j];
}
}
dp[i]=maxx+1;
maxnum=max(dp[i],maxnum);
}
int start=1;
prin[maxnum+1]=-1;
for(int i=maxnum;i>=1;i--){
int mi=0x3f3f3f3f;
for(int j=start;j<=n;j++){
if(dp[j]==i&&s1[j]>=prin[i+1]&&s1[j]<mi){
mi=s1[j];
start=j;
}
}
prin[i]=mi;
}
for(int i=maxnum;i>=1;i--){
if(i==1)printf("%d\n",prin[i]);
else printf("%d ",prin[i]);
}
/********* End *********/
return 0;
}
测试输入:
10
100 11 45 16 17 19 88 22 23 99
预期输出:
11 16 17 19 22 23 99