NYOJ 823 人形序列

来源:互联网 发布:好学近乎知水印 编辑:程序博客网 时间:2024/05/06 17:30

题目信息:

人形序列

时间限制:1000 ms  |  内存限制:65535 KB
难度:2
描述
给你一个序列,你能求出最长的人字形子序列吗?即先递增后递减且递增递减长度相等的序列,且子序列中相邻元素不相同
输入
多组测试数据,每组测试数据第一行输入一个N(1<=N<=50),第二行输入N个数即为给定序列, 输入数在int范围内,输入0程序结束
输出
输出最长人字形序列长度
样例输入
51 3 5 4 291 2 2 3 5 1 2 3 10
样例输出
55
提示
第二组数据的其中一个满足条件子序列为:2 3 5 2 1

解题思路:

也算是动态规划的最长子序列问题吧,要求对称,可以设置两个动态规划数组,一个存由前向后的最长递增子序列,另一个存由后向前的最长递增子序列。最后根据两个数组的长度以及最后一位的大小来判断和输出即可。

代码部分:

#include <stdio.h>#include <string.h>int insert(int dp[],int k,int x){int i;for(i=k;i>=0;i--){if(dp[i]<x){dp[i+1]=x;if(k==i){return 1;}else{return 0;}}}}int main(){int n,i,j,head,tail;int seq[55],dp1[30],dp2[30];dp1[0]=-0xffffff;dp2[0]=-0xffffff;while(scanf("%d",&n)&&n){head=0;tail=0;for(i=0;i<n;i++)scanf("%d",&seq[i]);if(n<=2){printf("1\n");continue;}for(i=0,j=n-1;i<=j;i++,j--){if(i==j){if(insert(dp1,head,seq[i])==1)head++;break;}while(insert(dp1,head,seq[i])!=1){i++;if(i>=j)break;}if(i>j)break;else if(i<j)head++;elsei--;while(insert(dp2,tail,seq[j])!=1){j--;if(i>=j)break;}if(i>j)break;else if(i<j)tail++;elsej++;}if(dp1[head]>dp2[tail]){if(head>tail)printf("%d\n",tail*2+1);elseprintf("%d\n",head*2-1);}else if(dp1[head]==dp2[tail]){if(head>=tail)printf("%d\n",tail*2-1);elseprintf("%d\n",head*2-1);}else{if(head>=tail)printf("%d\n",tail*2-1);elseprintf("%d\n",head*2+1);}}return 0;}




0 0
原创粉丝点击