Wave(ccpc江西省赛)

该博客探讨了如何解决一个计算机竞赛问题,即在给定序列中找到最长的满足特定条件(奇数位置和偶数位置元素不同且相同位置的元素相同)的子序列,称为'波浪'子序列。博主提出了一个策略,通过预处理数组来降低复杂度,以枚举奇偶位置的元素并更新最长子序列的长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem Description

Avin is studying series. A series is called "wave" if the following conditions are satisfied:
1) It contains at least two elements;
2) All elements at odd positions are the same;
3) All elements at even positions are the same;
4) Elements at odd positions are NOT the same as the elements at even positions.
You are given a series with length n. Avin asks you to find the longest "wave" subseries. A subseries is a subsequence of a series.

Input

The first line contains two numbers n, c (1 ≤ n ≤ 100, 000, 1 ≤ c ≤ 100). The second line contains n integers whose range is [1, c], which represents the series. It is guaranteed that there is always a "wave" subseries.

Output

Print the length of the longest "wave" subseries.

Sample Input

5 3 1 2 1 3 2

Sample Output

4

思路:由于c的范围只有100,我们分别枚举奇偶位置的数值a、b,更新出最大长度ans。为了减少每组a、b查找子串长度的复杂度,我们预处理一个v[i][j]表示  数值i的第j个值的位置在哪里。

#include<iostream>
#include<cstdio>
#include<vector>
#define ll long long
using namespace std;
vector<int>v[200];
int a[1008611];
int main(){
    int n,c,ans=0;
    cin>>n>>c;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        v[a[i]].push_back(i);
    }
    for(int i=1;i<=c;i++){
        for(int j=1;j<=c;j++){
            if(i==j)continue;
            int p1=0,p2=0,flag=0,len=0,fir=0,sec=0;
            while(p1<v[i].size()&&p2<v[j].size()){
                if(flag==0)
                {
                    while(p1<v[i].size()&&v[i][p1]<sec)p1++;
                    if(p1<v[i].size()){
                        fir=v[i][p1];
                        len++;
                    }
                    flag=1;
                }
                else if(flag==1)
                {
                    while(p2<v[j].size()&&v[j][p2]<fir)p2++;
                    if(p2<v[j].size()){
                        len++;
                        sec=v[j][p2];
                    }
                    flag=0;
                }
            }
            ans=max(ans,len);
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值