UVA103 转化相对位置+最长上升子序列

题目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=114&page=show_problem&problem=47

题目描述:

给定一个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]!='\0') n=n*10+s[1]-'0';
            gets(s);
            init();
        }else {printf("%d\n",slove());}
    }
    return 0;
}

  

 

posted @ 2013-11-27 22:48  little_w  阅读(229)  评论(0编辑  收藏  举报