最长连续相异子序列 STL.MAP + DP

问题 H: 最长连续相异子序列
时间限制: 5 Sec  内存限制: 128 MB
提交: 572  解决: 75
[提交][状态][讨论版]
题目描述
 给出一个含有n个数的序列,求一段最长的连续子序列的长度且这个子序列中不存在相同的数;

输入
题目由多组数据组成,不超过30组
每组数据由两行组成,第一行输入一个数n(0<n<=105)表示序列的长度;接下来一行是n个整数,每个数大于0且小于231;
输入以EOF结尾。
输出
对于每组测试数据,输出一行表示最长连续相异子序列的长度;

样例输入
10
1 2 3 4 5 1 2 3 4 5
6
1 1 1 1 1 1
样例输出
5
1
提示
[提交][状态][讨论版]

来源: http://acm.hnust.edu.cn/JudgeOnline/problem.php?cid=1203&pid=7

/*!思路:
        对于给定的序列从第一位开始读取处理
        设定limit为last限制,MAX为最大长度
        若第i位不在map中
            将A[i]放到map内,info为其序号i
            将i-last与MAX比较赋最大值与MAX
        否则
            将获得上一个A[i]的序号记为last
            当前位置记为now
            now - last 即为子序列长度
            如果当前last>=limit则将now-last与MAX比较赋最大值于MAX 
            否则将 now-limit 与MAX比较赋值
        循环结束
!*/
    #include <cstdio>
    #include <map>
    using namespace std;
    #define M_L 100000
    int A[M_L+1];int len;
    int Cal(void)
    {
        int limit=0,MAX=0;
        map<int,int> MAP;
        map<int,int>::iterator it;
        for(int i=1;i<=len;i++) scanf("%d",&A[i]);
        //printf("len==%d\n",len);
        for(int i=1;i<=len;i++)
        {
//printf("\n*******************\n");
//for(it = MAP.begin();it!=MAP.end();it++)
//printf("第%d次操作  值为%d 序号%d\n",i,(*it).first,(*it).second);
            it=MAP.find(A[i]);
            if(it==MAP.end())    
            {
                MAP[A[i]]=i;
                MAX = MAX>i-limit? MAX : i-limit; //这里也要执行操作 // 测试数据10 ---》 1 2 2 3 1 2 5 7 8 2
            }
            else
            {

                int last = (*it).second;
                int now  = i;
                last = last>=limit? last:limit ;
//printf("limit = %d,last == %d ,now == %d\n",limit,last ,now);
                (*it).second = now; limit = last;//更新位置
//printf("new limit = %d\n",limit);
                MAX = MAX>now-last? MAX : now-last;
//printf("MAX == %d \n",MAX);
            }
        }
        return MAX;
    }
    int main()
    {
//freopen("D:\\test.txt","r",stdin);
        while(~scanf("%d ",&len)) printf("%d\n",Cal());
        return 0;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值