题目描述:
给定一个1--n乱序的标准序列
输入另一个待求1--n序列,求解到底待求序列中最大有多长的连续的数,符合标准序列的相对顺序。
例如: 2 4 1 3 5
3 1 4 5 2
答案:2(4,5或1,5或3,5)
算法描述:
一、这到问题关键是在于思维:因为要考虑到所有情况是不可能的,有因为在乱序上不好做操作,所以要做预处理:
1、第一种,将标准序列做变换,变成1234....n,记录变化方式,对后续待求序列做相同变换(程序一)
2、第二种,对于标准序列中的每个数字按顺序设置权重,对待求序列用对应权重生成新序列(程序二)
二、最后求一个最长上升子序列即可。
三、输入很难处理
代码一:
#include<stdio.h>
#include<string.h>
#define maxn 25
int n;
char s[maxn*5];
int p[maxn];//存储第i个数应该换到p1[i]的位置上
int num[maxn];//放置数字序列
int anp[maxn];//求LIS的序列
int string_scanf(int i)//返回字符串中的第i个数字
{
int t=0;
int p=0;
while (p<strlen(s)){
int nu=s[p]-'0';
if (s[p+1]<='9' && s[p+1]>='0') {nu=nu*10+s[p+1]-'0';p+=3;} else p+=2;
t++;
if (t==i) return nu;
}
}
void getnum(){//string->num
for(int i=1;i<=n;i++)
num[i]=string_scanf(i);
}
void init(){//生成应该置换的序列
getnum();
for(int i=1;i<=n;i++){
p[i]=num[i];
}
}
int LIS()
{
int dp[maxn];
int ans=1;
for(int i=1;i<=n;i++){
dp[i]=1;
for(int j=1;j<=i;j++){
if(anp[i]>anp[j] && dp[i]<dp[j]+ 1){
dp[i]=dp[j]+1;
if(dp[i]>ans){
ans=dp[i];
}
}
}
}
return ans;
}
int slove(){
getnum();
for(int i=1;i<=n;i++){
anp[p[i]]=num[i];
}
for(int i=1;i<=n;i++)
return LIS();
}
int main(){
while(gets(s)){//读写部分
if (strlen(s)<=2){
n=s[0]-'0';
if (s[1]!=' ') n=n*10+s[1]-'0';
gets(s);
init();
}else {printf("%d
",slove());}
}
return 0;
}