D Game
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1063 Accepted Submission(s): 380
Problem Description
众所周知,度度熊喜欢的字符只有两个:B 和D。
今天,它发明了一个游戏:D游戏。
度度熊的英文并不是很高明,所以这里的D,没什么高深的含义,只是代指等差数列[(等差数列百科)](http://baike.baidu.com/view/62268.htm)中的公差D。
这个游戏是这样的,首先度度熊拥有一个公差集合 {D},然后它依次写下 N个数字排成一行。游戏规则很简单:
1. 在当前剩下的有序数组中选择 X(X≥2) 个连续数字;
2. 检查 1选择的 X个数字是否构成等差数列,且公差 d∈{D};
3. 如果 2满足,可以在数组中删除这 X个数字;
4. 重复 1−3 步,直到无法删除更多数字。
度度熊最多能删掉多少个数字,如果它足够聪明的话?
今天,它发明了一个游戏:D游戏。
度度熊的英文并不是很高明,所以这里的D,没什么高深的含义,只是代指等差数列[(等差数列百科)](http://baike.baidu.com/view/62268.htm)中的公差D。
这个游戏是这样的,首先度度熊拥有一个公差集合 {D},然后它依次写下 N个数字排成一行。游戏规则很简单:
1. 在当前剩下的有序数组中选择 X(X≥2) 个连续数字;
2. 检查 1选择的 X个数字是否构成等差数列,且公差 d∈{D};
3. 如果 2满足,可以在数组中删除这 X个数字;
4. 重复 1−3 步,直到无法删除更多数字。
度度熊最多能删掉多少个数字,如果它足够聪明的话?
Input
第一行一个整数
T,表示
T(1≤T≤100) 组数据。
每组数据以两个整数 N, M 开始 。接着的一行包括 N 个整数,表示排成一行的有序数组 Ai。接下来的一行是 M 个整数,即给定的公差集合 Di。
1≤N,M≤300
−1 000 000 000≤Ai,Di≤1 000 000 000
每组数据以两个整数 N, M 开始 。接着的一行包括 N 个整数,表示排成一行的有序数组 Ai。接下来的一行是 M 个整数,即给定的公差集合 Di。
1≤N,M≤300
−1 000 000 000≤Ai,Di≤1 000 000 000
Output
对于每组数据,输出最多能删掉的数字 。
Sample Input
3 3 1 1 2 3 1 3 2 1 2 4 1 2 4 2 1 3 4 3 1 2
Sample Output
3 2 4
#include<bits/stdc++.h>
using namespace std;
const int maxn=303;
int dp[maxn][maxn],a[maxn];
bool vis[maxn][maxn];
int main()
{
int T;scanf("%d",&T);
while(T--)
{
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
{
int x;scanf("%d",&x);
for(int j=1;j<=n;j++)
{
for(int k=j+1;k<=n;k++)
{
if(a[k]-a[j]==x)
vis[j][k]=1;
}
}
}
for(int i=n;i>=1;i--)
{
for(int j=i+1;j<=n;j++)
{
if(vis[i][j]&&dp[i+1][j-1]==j-i-1)
dp[i][j]=j-i+1;
for(int k=i+1;k<j;k++)
{
bool x1=0,x2=0;
if(vis[i][k]&&dp[i+1][k-1]==k-i-1)
dp[i][j]=max(dp[i][j],dp[k+1][j]+k-i+1),x1=1;
if(vis[k][j]&&dp[k+1][j-1]==j-k-1)
dp[i][j]=max(dp[i][j],dp[i][k-1]+j-k+1),x2=1;
if(x1&&x2&&a[j]-a[k]==a[k]-a[i])
dp[i][j]=j-i+1;
dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]);
}
}
}
printf("%d\n",dp[1][n]);
}
return 0;
}