每一年都奔走在自己热爱里

没有人是一座孤岛,总有谁爱着你

CodeTON Round 5 (Div. 1 + Div. 2, Rated, Prizes!)C

CodeTON Round 5 (Div. 1 + Div. 2, Rated, Prizes!)C

C(dp)

C

题目给出一个数组,我们可以在这一个数组里面找出aiaj其中ij不相等,并保证ai=aj,这样我们就可以把ij这一段区间的所有数字都删除,问我们怎样删除才可以使删除的数字数量最多

很明显,这是一个dp,但是如果对于每一对相同数字,根据这个得到不同的线段,然后一个一个的求,会TLE,所以我们需要一个特殊的操作让我们只需要那个最优的情况(求i之前的所有的max(dpj)会超时,但是如果预处理出mxi=max(dpi),但是我们不知道这个mxi1的开始在哪一个位置,无法求出这一段的贡献

我们可以设置dpii个位置的最大删除数量为多少

然后我们这里我预处理的mxi=max(dpii),这样就相当于把dpii的位置看成往左挪动到位置0,这样,后面如果我们用到它,我们只要知道右端点即可,即dpi+1=mxa[i]+i+1,代表着0到当前位置i的距离,也可以理解为dpi+1=dpi1+i(i1)+1(如果这一个mx_a_i是从dpi1那里得来的)

这样就很好写了

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
#include <bitset>
#include <numeric>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define eps 1e-6
#define mem(a,b) memset((a),(b),sizeof(a))
const int maxn=2e5+10;
const int mod=998244353;
int t;
int n,a[maxn];
void solve()
{
  cin>>n;
  for (int i=1;i<=n;i++)
  {
    cin>>a[i];
  }
  vector<int>dp(n+2,0),mx(n+2,-inf);
  for(int i=1;i<=n;i++)
  {
    dp[i+1]=max(dp[i],mx[a[i]]+i+1);
    mx[a[i]]=max(mx[a[i]],dp[i]-i);//mx记录的是在某一个数,并以其中一个位置作为起点的最大值,这样,后面如果要用到这一个数,我们可以直接把mx+pos+1,因为我们之前已经减去了本身的距离
  }
  int ans=dp[n+1];
  cout<<ans<<"\n";
  return ;
}
signed main ()
{
  //ios;
  cin>>t;
  while (t--)
  {
    solve();
  }
  system ("pause");
  return 0;
}
posted @   righting  阅读(77)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示