• Hdu5693 D Game


    D Game

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 905    Accepted Submission(s): 324

    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
    Source
    分析:挺好的一道题.
       删数,区间会变动,支持O(n^3)的做法,很显然,这就是一道区间dp题.如果直接设状态f[i][j]表示区间[i,j]最多能删多少个数,不好转移,不知道剩下还有哪些数能够删.
       把最优性问题转化成判断可行性问题. 令f[i][j]表示区间[i,j]的数能不能被删光. 有一个结论:每次删数只需要删2个或者3个.为什么可以这样呢?如果一次删的数的个数>3个,那么完全可以把它们拆成2个和3个地去删.可以利用这个结论来进行转移.
       区间[i,j]有两种可能的情况:1.i和j被删了.  2.i和j没有被删.
       对于第一种情况,枚举一个k,如果f[i][k] = f[k + 1][j] = 1,那么f[i][j] = 1.
       对于第二种情况,有两种决策:要么删2个数,要么删3个数,删两个数的话就只能删i和j咯,如果f[i + 1][j - 1] = 1并且a[j] - a[i]在给定的公差集合里,那么f[i][j] = 1. 如果是删3个数,枚举一个中间点k,f[i + 1][k - 1] = f[k + 1][j - 1] = 1并且a[j] - a[k] = a[k] - a[i]并且a[j] - a[k]出现在了公差集合中,那么f[i][j] = 1.
       这只是处理出了区间能否被删除,如何求删除的数的最大数量呢?
       每个数只能被删一次,可以将之前处理的f[i][j]看作一条条线段[i,j],要找不相交的线段使得覆盖的长度最大,这个O(n^2)dp以下就好了.
       最近做的几道区间dp题都是很有套路的,首先是很容易能够看出区间dp的特征,设出基本状态,如果不能转移就加维度.所求的一般都是最值,如果状态不能直接表示成最值,就表示为是否可行.
    #include <map>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    map<ll,int> s;
    ll T,n,m,can[310][310],f[310],a[310];
    
    int main()
    {
        scanf("%lld",&T);
        while (T--)
        {
            s.clear();
            memset(can,0,sizeof(can));
            memset(f,0,sizeof(f));
            scanf("%lld%lld",&n,&m);
            for (int i = 1; i <= n; i++)
                scanf("%lld",&a[i]);
            for (int i = 1; i <= m; i++)
            {
                ll x;
                scanf("%lld",&x);
                s[x] = 1;
            }
            for (int len = 2; len <= n; len++)
            {
                for (int i = 1; i + len - 1 <= n; i++)
                {
                    int j = i + len - 1;
                    if (len == 2)
                    {
                        if (s[a[j] - a[i]])
                            can[i][j] = 1;
                        continue;
                    }
                    if (len == 3)
                    {
                        if (a[j] - a[j - 1] == a[j - 1] - a[i] && s[a[j] - a[j - 1]])
                            can[i][j] = 1;
                        continue;
                    }
                    for (int k = i + 1; k < j - 1; k++)
                        if (can[i][k] && can[k + 1][j])
                            can[i][j] = 1;
                    if (can[i + 1][j - 1] && s[a[j] - a[i]])
                        can[i][j] = 1;
                    for (int k = i + 3; k < j - 2; k++)
                        if (can[i + 1][k - 1] && can[k + 1][j - 1] && a[j] - a[k] == a[k] - a[i] && s[a[j] - a[k]])
                            can[i][j] = 1;
                }
            }
            for (int i = 1; i <= n; i++)
                for (int j = 1; j < i; j++)
                    {
                        f[i] = max(f[i],f[i - 1]);
                        if (can[j][i])
                            f[i] = max(f[j - 1] + i - j + 1,f[i]);
                    }
            printf("%lld
    ",f[n]);
        }
    
        return 0;
    }
  • 相关阅读:
    pl/sql 导入csv到oracle时乱码问题
    mybatis if判断两个值是否相等存在的坑啊
    mybatis #与$占位符的区别
    NPM使用前设置和升级
    AWS ec2的ubuntu14.04上安装git服务
    Apache性能优化
    i5+GT730+B85安装OSX10.10.5 (Yosemite Install(14F27).cdr)
    IE的css hack
    sourcetree(mac)设置代理
    webpack配置的说明
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8483234.html
Copyright © 2020-2023  润新知