题目链接:https://cn.vjudge.net/problem/HDU-5693

题意

中文题

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

  1. 在当前剩下的有序数组中选择X(X≥2) 个连续数字;
  2. 检查1选择的X个数字是否构成等差数列,且公差 d∈{D};
  3. 如果2满足,可以在数组中删除这X个数字;
  4. 重复 1−3 步,直到无法删除更多数字。

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

    n, m<=300

思路

一开始又没思路,最后还是老师给的答案。

现在想想的话,我们可以记住有哪些常见状态和转移,以便提升发展。

设dp[i]为前i个数字下能删去的数字和,那么转移方程:

dp[i]=max(dp[i-1], max( dp[j-1]+i-j+1 | [i, j]为可删去的区间 ))

好了转移方程有了,那么可删区间怎么来?

这里可以按区间长度动规,我是怎么也没想到这点:

我们将x表示为某等差序列,[]表示可删子区间,那么整个可删区间可以表示为:

例子:x[]x[][]x[][][]xxx[]x[]

那么为了唯一的(保证一个DAG)分开所有可删子区间,我们可以这样子:

  1. 区间可分为两个可删区间,dp=max(dp[i][k]+dp[k+1][j])
  2. 区间两端可以删去等差数列,dp=max(dp[i+1][j-1])
  3. 区间两端和中间可以删去等差数列,dp=max(dp[i+1][k-1]+dp[k+1][j-1])

那么状态转移就可以写了。

提交过程

AC

代码

#include <set>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=300+20, maxm=maxn;
set<long long> isd;
int num[maxn], dp[maxn];
bool seg[maxn][maxn];
long long tmp; int main(void){
int T, n, m; scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &m);
isd.clear();
memset(seg, false, sizeof(seg));
for (int i=1; i<=n; i++) scanf("%d", &num[i]), seg[i][i-1]=true;
for (int i=0; i<m; i++) scanf("%lld", &tmp), isd.insert(tmp); for (int len=1; len<n; len++)
for (int i=1; i+len<=n; i++){
int j=i+len; if (seg[i+1][j-1] && isd.count(num[j]-num[i]))
seg[i][j]=true;
if (!seg[i][j]) for (int k=i+1; k<j; k++){
seg[i][j]=seg[i][k]&&seg[k+1][j]; // 1
if (seg[i][j]) break;
}
if (!seg[i][j]) for (int k=i+1; k<j; k++){
if (num[k]-num[i]==num[j]-num[k] && isd.count(num[k]-num[i])){
seg[i][j]=seg[i+1][k-1]&&seg[k+1][j-1]; // 2
if (seg[i][j]) break;
}
}
} memset(dp, 0, sizeof(dp));
for (int i=1; i<=n; i++){
dp[i]=dp[i-1];
for (int j=1; j<=i-1; j++) if (seg[j][i])
dp[i]=max(dp[i], dp[j-1]+i-j+1); // 3
}printf("%d\n", dp[n]);
} return 0;
}
Time Memory Length Lang Submitted
561ms 1360kB 1470 G++ 2018-08-07 02:54:18

HDU-5693 D Game 动态规划 两次动规的更多相关文章

  1. hdu 5693 && LightOj 1422 区间DP

    hdu 5693 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5693 等差数列当划分细了后只用比较2个或者3个数就可以了,因为大于3的数都可以由2和3 ...

  2. hdu 5693 D Game

    D Game HDU - 5693 众所周知,度度熊喜欢的字符只有两个:B 和D. 今天,它发明了一个游戏:D游戏. 度度熊的英文并不是很高明,所以这里的D,没什么高深的含义,只是代指等差数列[(等差 ...

  3. HDU——Monkey and Banana 动态规划

                                                                       Monkey and Banana Time Limit:2000 ...

  4. HDU 1159 Common Subsequence (动规+最长公共子序列)

    Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  5. 【noip 2009】 乌龟棋 记忆化搜索&动规

    题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...

  6. LCS(最长公共子序列)动规算法正确性证明

    今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下, ...

  7. - > 动规讲解基础讲解一——01背包(模板)

    作为动态规划的基础,01背包的思想在许多动规问题中会经常出现,so,熟练的掌握01背包的思路是极其重要的: 有n件物品,第i件物品(I = 1,2,3…n)的价值是vi, 重量是wi,我们有一个能承重 ...

  8. 关于DP动规

    今天学了动规,简单记录一下自己理解了的:(要不俺就忘了) 首先,啥是DP??? 动态规划,其实就是组合子问题的解来解决整个问题的解,由于每个子问题他只判断一次,所以不会重复计算,那就很牛啊!!! 专业 ...

  9. NOIP2013 提高组day2 2 花匠 动规 找拐点 树状数组

    花匠 描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致. 具体 ...

随机推荐

  1. node——进阶版服务器根据不同请求作出不同响应+响应html文件等文件

    文件目录结构如下 resource文件里面放了css文件和图片等,view文件里面是html文件 <!DOCTYPE html> <html lang="en"& ...

  2. [HDU1052]Tian Ji -- The Horse Racing(田忌赛马)

    题目大意:田忌赛马问题,给出田忌和齐威王的马的数量$n$和每匹马的速度$v$,求田忌最多赢齐威王多少钱(赢一局得200,输一局扣200,平局不得不扣). 思路:贪心. 1.若田忌最慢的马可以战胜齐王最 ...

  3. [luogu2059 JLOI2013] 卡牌游戏 (概率dp)

    题目描述 N个人坐成一圈玩游戏.一开始我们把所有玩家按顺时针从1到N编号.首先第一回合是玩家1作为庄家.每个回合庄家都会随机(即按相等的概率)从卡牌堆里选择一张卡片,假设卡片上的数字为X,则庄家首先把 ...

  4. [AtCoder Regular Contest 083] Bichrome Tree

    树形DP. 每个点有两个属性:黑色点的权值和,白色点权值和,一个知道另一个也一定知道. 因为只要子树的和它相等的点得权值和不超过x[u],u点的权值总能将其补齐. 设计状态f[u]表示以u为根的子树, ...

  5. 小学生绞尽脑汁也学不会的python(异常,约束,MD5加密,日志处理)

    小学生绞尽脑汁也学不会的python(异常,约束,MD5加密,日志处理) 异常处理(处理) 1.产生异常.raise 异常类(),抛出异常2. 处理异常: try: xxxxx # 尝试执行的代码. ...

  6. SVN提交代码时报405 Method Not Allowed

    原因: 1.删除了某个文件夹,然后又创建了一个同名文件夹 2.之前执行过Add操作,但没上传代码,在电脑上提交了同路径的代码,再次上传时会报错 解决方法: 1. 删除出现错误的文件夹 2. SVN U ...

  7. 洛谷P5269 欧稳欧再次学车

    正常模拟就好~ 首先初始化:转速=l, 档位=1 然后读入数据 由于先要处理换挡操作,所以我们先按照x处理,再按照y处理 当x=0时,档位+1,转速=l 当x=1时,档位-1,转速=r 当y=1时,转 ...

  8. UML基础知识点

    UML   :   unified Modeling Language  统一建模语言 1.对系统问题进行分析和建模 2.非专利的第三代建模和规约语言 3.UML是一种开放的方法.用于说明.可视化.构 ...

  9. HTML5简单进度环插件

    前几天做了一个进度条的插件.今天我用HTML5的arc做一个简单的进度环的插件. 代码演示 事实上非常easy的.相同,我们先用一个实例: 配置js代码 var setting = { id: &qu ...

  10. Android集成一个新产品时,lunch的product name和device name注意事项

    Android系统lunch一个当前的Product大概流程包括下面几个部分: 1. lunch确定TARGET_PRODUCT.一般位于vendor/device/build/target/prod ...