题意:要找出一个数组中满足b2−b1≤b3−b2≤⋯≤bt−bt−1 的最大的t
思路:如果求出dp[i][j]以后,就已经计算了一个最小的k,使得aj-ai>=ci-ck,那么在计算dp[i][j+1]的时候,从k到i这部分可以不用算了
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[1<<22+5];
int dp[3000][3000];
int main()
{
// freopen("data.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;++i)
{
scanf("%d",&a[i]);
}
sort(a,a+n);
for(int i=0;i<min(n+1,2999);++i)
{
for(int j=0;j<min(n+1,2999);++j)
{
if(i!=j)
dp[i][j]=2;
else dp[i][j]=0;
}
}
int tot=0;
int rec=a[0];
int num=0;
for(int i=0;i<n;++i)
{
if(a[i]==rec)num++;
else
{
rec=a[i];
dp[tot][tot]=num;
tot++;
num=1;
}
}
dp[tot][tot]=num;
int u=unique(a,a+n)-a;
for(int i=0;i<u;++i)
{
int j,k;
j=i+1;
k=i;
while(j<u)
{
if(a[i]-a[k]<=a[j]-a[i]&&k>=0){
dp[i][j]=max(dp[i][j],dp[k][i]+1);
if(k>=0)k--;
}
else
{
j++;
dp[i][j]=max(dp[i][j],dp[i][j-1]);
}
}
}
int ans=0;
for(int i=0;i<u;++i)
{
for(int j=0;j<=i;++j)
{
ans=max(ans,dp[j][i]);
// cout<<i<<' '<<j<<' '<<dp[j][i]<<endl;
}
}
printf("%d\n",ans);
}
return 0;
}
−b1≤b3−b2≤⋯≤bt−bt−1最大