Find Sequence
Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 386 Accepted Submission(s): 126
Problem Description
Give you an positive integer sequence
a1,a2,…,ai,…,an
, and they satisfy
a1+a2+…+ai+…+an=M(0<M≤222)
.
We can find new sequence b1=aid1,b2=aid2,…,bx=aidx,…,by=aidy,…,bt=aidt , where if x != y then idx!=idy . and this sequence satisfy:
(1) b1≤b2≤…≤bt
(2) b2−b1≤b3−b2≤⋯≤bt−bt−1
We can find many sequences b1,b2,b3,…,bt . But we only want to know maximum t.
We can find new sequence b1=aid1,b2=aid2,…,bx=aidx,…,by=aidy,…,bt=aidt , where if x != y then idx!=idy . and this sequence satisfy:
(1) b1≤b2≤…≤bt
(2) b2−b1≤b3−b2≤⋯≤bt−bt−1
We can find many sequences b1,b2,b3,…,bt . But we only want to know maximum t.
Input
The first line in the input file is an Integer
T(1≤T≤30)
.
The first line of each test case contains two integer n,M(0<M≤222) .
Then a line have n integer, they represent a1,a2,…,ai,…,an .
The first line of each test case contains two integer n,M(0<M≤222) .
Then a line have n integer, they represent a1,a2,…,ai,…,an .
Output
For each test case, output the maximum t.
Sample Input
2 6 19 3 2 1 3 4 6 1 4194304 4194304
Sample Output
5 1HintFor the first testcase, The Sequence is 1 2 3 4 6
然后用dp[i][j]表示从当前下标为i到j的最大数量,就有dp[i][j]=max(dp[k][i]+1)(k<=i)
但是O(n³)会炸,所以可以用单调性优化,每次k~i只要用前面的就好了,不需要重新计算,可以优化到O(n²)
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define M 3010
#define N 4194310
int a[N];
int dp[M][M];
int main()
{
int T;
int n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
sort(a,a+n);
int num=1,cnt=0;
for(int i=1; i<n; i++)
{
if(a[i]==a[i-1]) num++;
else
{
dp[cnt][cnt]=num;
cnt++;
num=1;
}
}
dp[cnt][cnt]=num;
int t=unique(a,a+n)-a;
for(int i=0;i<t;i++)
for(int j=i+1;j<t;j++)
dp[i][j]=1;
for(int i=0; i<t; i++)
{
int k=i,j=i+1;
while(j<t)
{
if(a[i]-a[k]<=a[j]-a[i]&&k>=0)
{
dp[i][j]=max(dp[i][j],dp[k][i]+1);
k--;
}
else
{
j++;
dp[i][j]=max(dp[i][j],dp[i][j-1]);
}
}
}
int ans=0;
for(int i=0; i<t; i++)
for(int j=i; j<t; j++)
ans=max(ans,dp[i][j]);
printf("%d\n",ans);
}
return 0;
}