以下是从中文翻译成人话的题面:

  给定一个长度小于等于500的序列,每个数字代表一个颜色,每次可以消掉一个回文串,问最多消几次可以消完?

(7.16)

  这个题从洛谷pend回来以后显示有103个测试点(满屏的AC好爽……

  上午考试的时候这个题直接用马拉车暴力贪心骗了十五分。然而每次消掉一个最长的回文串并不一定是最优的策略,这道题要用DP来做。

  设计状态f[l, r]表示消掉原串这段区间内串的最小代价。老师说直接递推不好搞,应该是因为这个循环的阶段不好确定。考虑用记忆化搜索来转移。

  四种情况:

  1、l = r,直接return 1;

  2、[l, r]是回文的,return 1;

  3、s[l] == s[r],转移表示为update(f[l, r], f[l + 1][r - 1]);

    这是因为我们可以在进行[l + 1, r - 1]的最后一次操作时顺手把两端消掉。

  4、一般情况:枚举每个中间点mid,取分成的两个区间代价和的最小值。

代码:

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #define maxn 510
  5. using namespace std;
  6. void open_file(string s) {
  7. string In = s + ".in", Out = s + ".out";
  8. freopen(In.c_str(), "r", stdin);
  9. freopen(Out.c_str(), "w", stdout);
  10. }
  11. int f[maxn][maxn], s[maxn], n;
  12. int dfs(int l, int r) {
  13. if (l == r)
  14. return 1;
  15. if (f[l][r])
  16. return f[l][r];
  17. bool flag = 1;
  18. for (int i = l; i <= (l + r) >> 1; ++i)
  19. if (s[i] != s[r - i + l]) flag = false;
  20. int ans = (int)1e9;
  21. if (flag)
  22. return f[l][r] = 1;
  23. if (s[l] == s[r])
  24. ans = dfs(l + 1, r - 1);
  25. for (int i = l; i < r; ++i)
  26. ans = min(ans, dfs(l, i) + dfs(i + 1, r));
  27. return f[l][r] = ans;
  28. }
  29. int main() {
  30. open_file("zuma");
  31. ios::sync_with_stdio(0);
  32. cin >> n;
  33. for (int i = 1; i <= n; ++i)
  34. cin >> s[i];
  35. cout << dfs(1, n);
  36. return 0;
  37. }

------------------------------------------------------------------------------

(7.17)其实这道题是可以直接递推的,阶段按照区间长度由短到长推进。(好像更好写……老师的话不能全信)

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #define maxn 510
  5. using namespace std;
  6. void open_file(string s) {
  7. string In = s + ".in", Out = s + ".out";
  8. freopen(In.c_str(), "r", stdin);
  9. freopen(Out.c_str(), "w", stdout);
  10. }
  11. int f[maxn][maxn], s[maxn], n;
  12. void dp() {
  13. memset(f, 0x3f, sizeof(f));
  14. for (int i = 1; i <= n; ++i)
  15. f[i][i] = 1;
  16. for (int k = 2; k <= n; ++k)
  17. for (int l = 1, r = k; r <= n; ++l, ++r) {
  18. bool flag = 1;
  19. for (int i = l; i <= (l + r) >> 1; ++i)
  20. if (s[i] != s[r - i + l]) flag = false;
  21. if (flag) {
  22. f[l][r] = 1;
  23. continue;
  24. }
  25. if (s[l] == s[r])
  26. f[l][r] = f[l + 1][r - 1];
  27. for (int i = l; i < r; ++i)
  28. f[l][r] = min(f[l][r], f[l][i] + f[i + 1][r]);
  29. }
  30. }
  31. int main() {
  32. open_file("zuma");
  33. ios::sync_with_stdio(0);
  34. cin >> n;
  35. for (int i = 1; i <= n; ++i)
  36. cin >> s[i];
  37. dp();
  38. cout << f[1][n];
  39. return 0;
  40. }

话说这个题的文件打开方式是从luogu学来的,整理成了一个接受文件名的函数。

【CF607B】Zuma——区间dp(记忆化搜索/递推)的更多相关文章

  1. (区间dp + 记忆化搜索)Treats for the Cows (POJ 3186)

    http://poj.org/problem?id=3186   Description FJ has purchased N (1 <= N <= 2000) yummy treats ...

  2. UVA 10003 Cutting Sticks 区间DP+记忆化搜索

    UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的 ...

  3. uva 10891 区间dp+记忆化搜索

    https://vjudge.net/problem/UVA-10891 给定一个序列x,A和B依次取数,规则是每次只能从头或者尾部取走若干个数,A和B采取的策略使得自己取出的数尽量和最大,A是先手, ...

  4. [每日一题2020.06.14]leetcode #70 爬楼梯 斐波那契数列 记忆化搜索 递推通项公式

    题目链接 题意 : 求斐波那契数列第n项 很简单一道题, 写它是因为想水一篇博客 勾起了我的回忆 首先, 求斐波那契数列, 一定 不 要 用 递归 ! 依稀记得当年校赛, 我在第一题交了20发超时, ...

  5. Ural 1183 Brackets Sequence(区间DP+记忆化搜索)

    题目地址:Ural 1183 最终把这题给A了.. .拖拉了好长时间,.. 自己想还是想不出来,正好紫书上有这题. d[i][j]为输入序列从下标i到下标j最少须要加多少括号才干成为合法序列.0< ...

  6. loj 1031(区间dp+记忆化搜索)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1031 思路:dp[i][j]表示从区间i-j中能取得的最大值,然后就是枚举分割点了. ...

  7. BZOJ1055[HAOI2008]玩具取名 【区间dp + 记忆化搜索】

    题目 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后 他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够 ...

  8. HDU 2517 / POJ 1191 棋盘分割 区间DP / 记忆化搜索

    题目链接: 黑书 P116 HDU 2157 棋盘分割 POJ 1191 棋盘分割 分析:  枚举所有可能的切割方法. 但如果用递归的方法要加上记忆搜索, 不能会超时... 代码: #include& ...

  9. hdu 4597 Play Game(区间dp,记忆化搜索)

    Problem Description Alice and Bob are playing a game. There are two piles of cards. There are N card ...

随机推荐

  1. JWT实现过程及应用

    jwt实现过程 # 用户登录,返回给客户端token(服务端不保存),用户带着token,服务端拿到token再校验; 1,提交用户名和密码给服务端,如果登陆成功,jwt会创建一个token,并返回; ...

  2. 阅读源码,通过LinkedList回顾基础

    目录 前言 类签名 泛型 Serializable和Cloneable Deque List和AbstractList RandomAccess接口(没实现) 变量 构造函数 常用方法 List体系下 ...

  3. Spark集群和任务执行

    [前言:承接<Spark通识>篇] Spark集群组件 Spark是典型的Master/Slave架构,集群主要包括以下4个组件: Driver:Spark框架中的驱动器,运行用户编写Ap ...

  4. 【SpringCloud】02.微服务与SpringCloud

    微服务的特点 一系列微小的服务共同组成 跑在自己的进程里 每个服务为独立的业务开发 独立部署 分布式管理 异构--不同的语言.不同类型的数据库 微服务架构的基础框架/组件 服务注册发现 服务网关(Se ...

  5. Spring中基于XML的声明式事务控制配置步骤

    1.配置事务管理器 2.配置事务的通知 此时,我们就需要导入事务的约束 tx名称空间和约束,同时也需要aop的 使用tx:advice标签配置事务通知 属性: id:给事务通知起一个唯一标识 tran ...

  6. selenium-常用操作总结

    from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome ...

  7. Sublime Text 3 安装插件与快捷键总结

    ublime Text 3 是一个了不起的软件.首先,它是一个干净,实用,可以快速的编写代码编辑器.它不仅具有令人难以置信的内置功能(多行编辑和VIM模式),而且还支持插件,代码片段和其他许多东西.很 ...

  8. Spring Boot 2.4 正式发布,重大调整!!!

    大家周末愉快啊,Spring Boot 2.3.5 没发布几天,你看,还是 1 周前发布的: 昨天又有粉丝留言说 Spring Boot 2.4.0 已经发布了: 我了个去,栈长赶紧跑到 Spring ...

  9. 利用日志文件getshell

    一.包含日志文件漏洞利用概述           当我们没有上传点,并且也没有url_allow_include功能时,我们就可以考虑包含服务器的日志文件.        利用思路也比较简单,当我们访 ...

  10. Ceph的参数mon_osd_down_out_subtree_limit细解

    前言 之前跟一个朋友沟通一个其他的问题的时候,发现了有一个参数 mon osd down out subtree limit 一直没有接触到,看了一下这个参数还是很有作用的,本篇将讲述这个参数的作用和 ...