思路:注意题目说的是删除连续的一段等差数列,2,3长度可以组成任意长度,b[i][j]表示第i个和第j个可以为等差,dp[i][j]表示i到j最长可删除等差数列
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=302; 4 5 int T; 6 int n,m; 7 int a[N],b[N][N],dp[N][N]; 8 9 void hdp(){ 10 for(int len=1;len<=n;len++){ 11 for(int l=1;l<=n;l++){ 12 int r=l+len; 13 if(r>n) break; 14 dp[l][r]=max(dp[l+1][r],dp[l][r-1]); 15 if(b[l][r]&&dp[l+1][r-1]==(r-l-1)) 16 dp[l][r]=max(dp[l][r],dp[l+1][r-1]+2); 17 for(int i=l+1;i<r;i++) 18 dp[l][r]=max(dp[l][r],dp[l][i]+dp[i+1][r]); 19 for(int i=l+1;i<=r;i++){ 20 if(b[l][i]&&dp[l+1][i-1]==(i-l-1)) 21 dp[l][r]=max(dp[l][r],dp[l+1][i-1]+2); 22 if(b[i][r]&&dp[i+1][r-1]==(r-i-1)) 23 dp[l][r]=max(dp[l][r],dp[i+1][r-1]+2); 24 if(b[l][i]&&b[i][r]&&a[i]-a[l]==a[r]-a[i]&&dp[l+1][i-1]==(i-l-1)&&dp[i+1][r-1]==(r-i-1)){ 25 dp[l][r]=max(dp[l][r],r-l+1); 26 } 27 } 28 } 29 } 30 } 31 32 void slove(){ 33 int x; 34 memset(dp,0,sizeof(dp)); 35 memset(b,0,sizeof(b)); 36 scanf("%d%d",&n,&m); 37 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 38 for(int i=1;i<=m;i++){ 39 scanf("%d",&x); 40 for(int j=1;j<=n;j++){ 41 for(int k=j+1;k<=n;k++){ 42 if(a[k]-a[j]==x) b[j][k]=1; 43 } 44 } 45 } 46 hdp(); 47 printf("%d\n",dp[1][n]); 48 } 49 int main(){ 50 scanf("%d",&T); 51 while(T--){ 52 slove(); 53 } 54 }
时间: 2024-11-02 23:24:05