HDOJ 5693 D Game
今天,它发明了一个游戏:D游戏。
度度熊的英文并不是很高明,所以这里的D,没什么高深的含义,只是代指等差数列[(等差数列百科)](http://baike.baidu.com/view/62268.htm)中的公差D。
这个游戏是这样的,首先度度熊拥有一个公差集合$\{D\}$,然后它依次写下$N$个数字排成一行。游戏规则很简单:
1. 在当前剩下的有序数组中选择$X (X \geq 2)$ 个连续数字;
2. 检查$1$选择的$X$个数字是否构成等差数列,且公差 $d\in \{D\}$;
3. 如果$2$满足,可以在数组中删除这$X$个数字;
4. 重复 $1 - 3$ 步,直到无法删除更多数字。
度度熊最多能删掉多少个数字,如果它足够聪明的话?
Input
第一行一个整数$T$,表示$T(1 \leq T \leq 100)$ 组数据。
每组数据以两个整数 $N$,$M$ 开始 。接着的一行包括 $N$ 个整数,表示排成一行的有序数组 $A_{i}$。接下来的一行是 $M$ 个整数,即给定的公差集合 $D_{i}$。
$1 \leq N, M \leq 300$
$-1\ 000\ 000\ 000 \leq A_{i}, D_{i} \leq 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
- 首先发现如果每次只删两个或者三个的话是肯定可以得到最优解的,因为任意长度的等差数列都可以由2和3组合出来。。短的反而好找。
而且它要求必须是删连续的数,这就类似于括号匹配,对于[A],只有A合法了[A]才合法。只不过还需要多考虑一种<|>构成的长度为三的括号。- 可以先预处理出那些段可以删,然后最后dp用f[i]表示前i个数最多可以删多少转移即可。
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<cmath>
- #include<algorithm>
- #include<map>
- #define ll long long
- #define maxn 305
- using namespace std;
- map<int,int> mmp;
- bool can[maxn][maxn];
- int f[maxn],n,m,T;
- int ans,a[maxn],now;
- inline void pre(){
- for(int i=;i<=n;i++) if(mmp.count(a[i]-a[i-])) can[i-][i]=;
- for(int i=;i<=n;i++) if((a[i-]<<)==a[i]+a[i-])
- if(mmp.count(a[i]-a[i-])) can[i-][i]=;
- for(int len=;len<=n;len++)
- for(int i=len,j=;i<=n;i++,j++){
- int tt=a[i]+a[j];
- bool flag=!(tt&);
- tt>>=;
- if(flag&&!mmp.count((a[i]-a[j])>>)) flag=;
- if(mmp.count(a[i]-a[j])&&can[j+][i-]){
- can[j][i]=;
- continue;
- }
- for(int k=j+;k<i;k++){
- if(can[j][k]&&can[k+][i]){
- can[j][i]=;
- break;
- }
- if(flag&&a[k]==tt&&can[j+][k-]&&can[k+][i-]){
- can[j][i]=;
- break;
- }
- }
- }
- }
- inline void dp(){
- for(int i=;i<=n;i++){
- f[i]=f[i-];
- for(int j=i-;j;j--) if(can[j][i]) f[i]=max(f[i],f[j-]+i-j+);
- }
- ans=f[n];
- }
- int main(){
- scanf("%d",&T);
- while(T--){
- memset(can,,sizeof(can));
- memset(f,,sizeof(f));
- mmp.clear(),ans=;
- scanf("%d%d",&n,&m);
- for(int i=;i<=n;i++) scanf("%d",a+i);
- for(int i=;i<=m;i++) scanf("%d",&now),mmp[now]=;
- pre();
- dp();
- printf("%d\n",ans);
- }
- return ;
- }
HDOJ 5693 D Game的更多相关文章
- HDOJ 1009. Fat Mouse' Trade 贪心 结构体排序
FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDOJ 2317. Nasty Hacks 模拟水题
Nasty Hacks Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- HDOJ 1326. Box of Bricks 纯水题
Box of Bricks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- HDOJ 1004 Let the Balloon Rise
Problem Description Contest time again! How excited it is to see balloons floating around. But to te ...
- hdoj 1385Minimum Transport Cost
卧槽....最近刷的cf上有最短路,本来想拿这题复习一下.... 题意就是在输出最短路的情况下,经过每个节点会增加税收,另外要字典序输出,注意a到b和b到a的权值不同 然后就是处理字典序的问题,当松弛 ...
- HDOJ(2056)&HDOJ(1086)
Rectangles HDOJ(2056) http://acm.hdu.edu.cn/showproblem.php?pid=2056 题目描述:给2条线段,分别构成2个矩形,求2个矩形相交面 ...
- 继续node爬虫 — 百行代码自制自动AC机器人日解千题攻占HDOJ
前言 不说话,先猛戳 Ranklist 看我排名. 这是用 node 自动刷题大概半天的 "战绩",本文就来为大家简单讲解下如何用 node 做一个 "自动AC机&quo ...
- 最近点对问题 POJ 3714 Raid && HDOJ 1007 Quoit Design
题意:有n个点,问其中某一对点的距离最小是多少 分析:分治法解决问题:先按照x坐标排序,求解(left, mid)和(mid+1, right)范围的最小值,然后类似区间合并,分离mid左右的点也求最 ...
- BFS(八数码) POJ 1077 || HDOJ 1043 Eight
题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...
随机推荐
- 如何写出规范的JavaScript代码
作为一名开发人员(WEB前端JavaScript开发),不规范的开发不仅使日后代码维护变的困难,同时也不利于团队的合作,通常还会带来代码安全以及执行效率上的问题.本人在开发工作中就曾与不按规范来开发的 ...
- GDB使用小记
By francis_hao Nov 7,2016 记录GDB常用功能. GDB可以让你查看一个程序在运行时其内部发生了什么,或者当一个程序崩溃时发生了什么(通过使用GDB查看core dum ...
- ambari server内存溢出
抛出的异常信息如下: java.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Me ...
- Windows下安装Mycat-web
Mycat-web是基于Mycat的一个性能监控工具,如:sql性能监控等. 在安装Mycat-web之前需要先安装Zookeeper: 可参考: http://blog.csdn.net/tlk20 ...
- vue入门知识
vue的特点在于:响应的数据绑定.组合的视图组件. vue的文件,分成三个部分<template>html模板</template> <script>js< ...
- MyEclipse快捷键大全(转)1
Ctrl+1 快速修复(最经典的快捷键,就不用多说了) Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加) Ctrl+Alt+↑ 复制当前行到上一行(复制增加) Alt+ ...
- 【STSRM12】夏令营
[题意]n个数划分成k段,每段的价值为段内不同数字的数量,求最大总价值 [算法]DP+线段树 [题解] f[i][j]表示前i个数字划分成j段的最大价值. f[i][j]=max(f[k][j-1]+ ...
- 谈谈openstack部署规模问题
理论上,单个openstack已设计成可水平扩展的系统,只要数据库足够快,消息总线足够多资源等,一个openstack系统可管理上千台物理服务器是没有问题的. 但是单个openstack规模大了之后, ...
- Swift “ambiguous use of operator '>'”
http://stackoverflow.com/questions/25458548/swift-ambiguous-use-of-operator 3down votefavorite I h ...
- selenium自动化添加日志
于logging日志的介绍,主要有两大功能,一个是控制台的输出,一个是保存到本地文件 先封装logging模块,保存到common文件夹命名为logger.py,以便于调用,直接上代码 filenam ...