cpp
#include<bits/stdc++.h>
using namespace std ;
using ll = long long;
using PII = pair<int,int>;
//using = pair<int,int>;
using VI = vector<int>;
const int mod = 10007;
const int limit = 30000;
int n,m,s;
int x;
int count_1(ll x){
int res=0;
while(x){
res += x&1;
x = x>>1;
}
return res;
}
void solve(){
cin>>n;
VI a(n+2);
VI l(n+2,-0x3f3f3f3f);
VI dp(n+2,0);
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
dp[i] = dp[i-1];
dp[i] = max(dp[i],i + l[a[i]]);
l[a[i]] = max(l[a[i]] , dp[i-1]-i+1);
}
cout<<dp[n]<<"\n";
}
int main(){
int t;
cin>>t;
while(t--){
solve();
}
}
先考虑构建一个朴素的做法
dp[i] = max(dp[i-1] , dp[j-1] + i - j +1) j <= i && a[j] == a[i]
很明显这是一个二重循环,但对于在一次 j 的循环中,dp[j-1] + i - j +1 其中i是不变的,
所以只需要记录下每个数字的最大的 dp[j-1] - j + 1 就可以在O(1) 时间内实现转移