题目大意:给你一个序列,让你从中找小于等于两个子序列,让他们的长度和最小,要求这两个序列中没有相同的数字
分析:
尺取法,首先对于尺取的L与R,再次尺取0到L与R到N,从中选择一段最长的连续序列,每次更新即可
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#include <set>
#include <vector>
using namespace std;
const int maxn = 1e5 + 10;
const int maxm = 1e3 + 10;
bool used[maxn];
int a[maxm];
int n;
int solve(int L,int R)
{
if(L>=R) return 0;
//else if(L==R) return 1;
int l=L,r=L;
int ans = 0;
// cout<<L<<"mmmm"<<R<<endl;
while(1)
{
while(r<R&&!used[a[r]])
{
used[a[r]]++;
r++;
}
//cout<<l<<"..."<<r<<endl;
if(l==R&&r==R) break;
ans = max(ans,r-l);
used[a[l]]=0;
l++;
if(l==R&&r==R) break;
}
// cout<<L<<" "<<R<<" "<<ans<<endl;
return ans;
}
int main()
{
int T;
scanf("%d",&T);
int kase = 0;
while(T--){
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
memset(used,0,sizeof(used));
int L = 0,R = 0;
int ans = 0;
while(1)
{
while(R<n&&!used[a[R]]){
used[a[R]]++;
R++;
ans = max(ans,R-L+max(solve(0,L),solve(R,n)));
}
// cout<<L<<" "<<R<<endl;
used[a[L]]=0;
L++;
ans = max(ans,R-L+max(solve(0,L),solve(R,n)));
if(L==n&&R==n) break;
}
printf("Case #%d: %d\n",++kase,ans);
}
return 0;
}