2016"百度之星" - 初赛(Astar Round2A) 1004 D Game 区间DP

Posted Meek

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2016"百度之星" - 初赛(Astar Round2A) 1004 D Game 区间DP相关的知识,希望对你有一定的参考价值。

D Game



Problem Description
 
众所周知,度度熊喜欢的字符只有两个:B 和D。

今天,它发明了一个游戏:D游戏。

度度熊的英文并不是很高明,所以这里的D,没什么高深的含义,只是代指等差数列[(等差数列百科)](http://baike.baidu.com/view/62268.htm)中的公差D。

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

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

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

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

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

度度熊最多能删掉多少个数字,如果它足够聪明的话?
 

 

Input
 
第一行一个整数T,表示T(1T100) 组数据。

每组数据以两个整数 NM 开始 。接着的一行包括 N 个整数,表示排成一行的有序数组 Ai。接下来的一行是 M 个整数,即给定的公差集合 Di

1N,M300

1 000 000 000Ai,Di1 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
 

 题解:

  设定dp[1][n]位最后答案

  每次去删除2个或者3个连续,或不连续的数

  暴力区间dp

  我是用dfs写的比较好理解

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include<map>
using namespace std;
const int N = 315, M = 30005, mod = 1e9 + 7, inf = 0x3f3f3f3f;
typedef long long ll;

int dp[N][N];
ll a[N],d;
map<ll,int > mp;
int dfs(int l,int r) {
    if(dp[l][r]!=-1) return dp[l][r];
    int& ret = dp[l][r];
    ret = 0;
    if(l>=r) return ret;

    if(l+1==r) {
        if(mp[a[r]-a[l]]) return (ret = 2);
        else return (ret = 0);
    }

    int tmp = 0;
    if(mp[a[r]-a[l]]) tmp+=2;
    if(dfs(l+1,r-1)==((r-1)-(l+1)+1)) ret = tmp+((r-1)-(l+1)+1);

    tmp = 0;
    if(a[l+1]-a[l]==a[r]-a[l+1]&&mp[a[r]-a[l+1]]) tmp+=3;
    if(dfs(l+2,r-1) == ((r-1)-(l+2)+1))ret = max(ret,tmp+((r-1)-(l+2)+1));

    tmp = 0;
    if(a[r-1]-a[l]==a[r]-a[r-1]&&mp[a[r]-a[r-1]]) tmp+=3;
    if(dfs(l+1,r-2) == ((r-2)-(l+1)+1)) ret = max(ret,tmp+((r-2)-(l+1)+1));

    for(int i=l+1;i<r;i++) {
        ret = max(ret,dfs(l,i)+dfs(i+1,r));
    }
    return ret;
}
int main() {
    int T,m,n;
    scanf("%d",&T);
    while(T--) {
        mp.clear();
        memset(dp,-1,sizeof(dp));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
        for(int i=1;i<=m;i++) scanf("%I64d",&d),mp[d] = 1;
        printf("%d\n",dfs(1,n));
    }
    return 0;
}

 

以上是关于2016"百度之星" - 初赛(Astar Round2A) 1004 D Game 区间DP的主要内容,如果未能解决你的问题,请参考以下文章

2016"百度之星" - 初赛(Astar Round2B)

2016"百度之星" - 初赛(Astar Round2A)

2016"百度之星" - 初赛(Astar Round2B)

2016"百度之星" - 初赛(Astar Round2A)

2016"百度之星" - 初赛(Astar Round2B)

2016"百度之星" - 初赛(Astar Round2A)All X(数学 矩阵)