观察到(2,3)=1,
在只能选择≥2个连续数字的情况下,无论一次删除几个数都可以拆分为删除两个或者三个数。
那么预处理删除两个和删除三个的情况,更大的区间合并。
样例良心啊(
我比较懒,就不log掉找公差了。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<ctime>
#include<cmath>
using namespace std;
int T, n, m, a[305], d[305], F[305][305];
int main() {
scanf("%d", &T);
while (T--) {
memset(F, 0, sizeof(F));
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
for (int i = 1; i <= m; ++i) {
scanf("%d", &d[i]);
}
for (int i = 2; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (a[i] - a[i-1] == d[j]) {
F[i-1][i] = 2;
break;
}
}
}
for (int t, i = 3; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
F[i-2][i] = max(F[i-2][i-1], F[i-1][i]);
if (a[i] - a[i-1] == d[j] && a[i-1] - a[i-2] == d[j]) {
F[i-2][i] = 3;
break;
}
}
}
for (int t, k = 4; k <= n; ++k) {
for (int i = k; i <= n; ++i) {
t = i-k+1;
for (int j = 1; j <= m; ++j) {
if (F[t][i-2]==k-2 && a[i]-a[i-1]==d[j]) {
F[t][i] = k;
break;
}
if (F[t+2][i]==k-2 && a[t+1]-a[t]==d[j]) {
F[t][i] = k;
break;
}
if (F[t][i-3]==k-3 && a[i]-a[i-1]==d[j] && a[i-1]-a[i-2]==d[j]) {
F[t][i] = k;
break;
}
if (F[t+3][i]==k-3 && a[t+1]-a[t]==d[j] && a[t+2]-a[t+1]==d[j]) {
F[t][i] = k;
break;
}
if (F[t+1][i-1]==k-2 && a[i]-a[t]==d[j]) {
F[t][i] = k;
break;
}
if (F[t+1][i-2]==k-3 && a[i]-a[i-1]==d[j] && a[i-1]-a[t]==d[j]) {
F[t][i] = k;
break;
}
if (F[t+2][i-1]==k-3 && a[i]-a[t+1]==d[j] && a[t+1]-a[t]==d[j]) {
F[t][i] = k;
break;
}
}
if (F[t][i] != k) for (int j = t; j < i; ++j) F[t][i] = max(F[t][i], F[t][j] + F[j+1][i]);
}
}
printf("%d\n", F[1][n]);
}
return 0;
} break;
}
if (F[t+1][i-2]==k-3 && a[i]-a[i-1]==d[j] && a[i-1]-a[t]==d[j]) {
F[t][i] = k;
break;
}
if (F[t+2][i-1]==k-3 && a[i]-a[t+1]==d[j] && a[t+1]-a[t]==d[j]) {
F[t][i] = k;
break;
}
}
if (F[t][i] != k) for (int j = t; j < i; ++j) F[t][i] = max(F[t][i], F[t][j] + F[j+1][i]);
}
}
printf("%d\n", F[1][n]);
}
return 0;
}