hdu 5693 D Game(区间DP)

题目链接:hdu 5693 D Game

题意:

首先度度熊拥有一个公差集合{D},然后它依次写下N个数字排成一行。游戏规则很简单:

1. 在当前剩下的有序数组中选择X(X2) 个连续数字;

2. 检查1选择的X个数字是否构成等差数列,且公差 d{D};

3. 如果2满足,可以在数组中删除这X个数字;

4. 重复 13 步,直到无法删除更多数字。

问最多能删掉多少个数字?

题解:

考虑区间DP,设f[i][j]表示数从i到j能否删除,由于等差数列性质,只需要单独考虑2个和3个数字的情况,其他都能由这两种情况组成。

最后再设dp[i]表示前i个最多能删除多少个,然后dp[i]=max(dp[i],dp[i-1]+j-i+1)。

 1 #include<bits/stdc++.h>
 2 #define mst(a,b) memset(a,b,sizeof(a))
 3 #define F(i,a,b) for(int i=a;i<=b;++i)
 4 using namespace std;
 5 typedef long long ll;
 6 
 7 const int N=307;
 8 int t,n,m,a[N],x,dp[N];
 9 map<int,int>cnt;
10 bool f[N][N];
11 
12 int main(){
13     scanf("%d",&t);
14     while(t--)
15     {
16         scanf("%d%d",&n,&m);
17         F(i,1,n)scanf("%d",a+i);
18         mst(f,0),cnt.clear();
19         F(i,1,m)scanf("%d",&x),cnt[x]=1;
20         F(l,2,n)F(i,1,n-l+1)
21         {
22             int j=i+l-1;
23             if(l==2&&cnt[a[i+1]-a[i]])f[i][j]=1;
24             else if(l==3&&2*a[i+1]==a[i]+a[i+2]&&cnt[a[i+1]-a[i]])f[i][j]=1;
25             else 
26             {
27                 if(cnt[a[j]-a[i]]&&f[i+1][j-1])f[i][j]=1;
28                 F(k,i+1,j-1)f[i][j]|=f[i][k]&f[k+1][j];
29             }
30         }
31         F(j,1,n)
32         {
33             dp[j]=dp[j-1];
34             F(i,1,j)if(f[i][j])dp[j]=max(dp[j],dp[i-1]+j-i+1);
35         }
36         printf("%d\n",dp[n]);
37     }
38     return 0;
39 }
View Code

 

posted @ 2017-02-22 16:25  bin_gege  阅读(304)  评论(0编辑  收藏  举报