【CF607B】Zuma——区间dp(记忆化搜索/递推)
以下是从中文翻译成人话的题面:
给定一个长度小于等于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,取分成的两个区间代价和的最小值。
代码:
- #include <cstdio>
- #include <iostream>
- #include <cstring>
- #define maxn 510
- using namespace std;
- void open_file(string s) {
- string In = s + ".in", Out = s + ".out";
- freopen(In.c_str(), "r", stdin);
- freopen(Out.c_str(), "w", stdout);
- }
- int f[maxn][maxn], s[maxn], n;
- int dfs(int l, int r) {
- if (l == r)
- return 1;
- if (f[l][r])
- return f[l][r];
- bool flag = 1;
- for (int i = l; i <= (l + r) >> 1; ++i)
- if (s[i] != s[r - i + l]) flag = false;
- int ans = (int)1e9;
- if (flag)
- return f[l][r] = 1;
- if (s[l] == s[r])
- ans = dfs(l + 1, r - 1);
- for (int i = l; i < r; ++i)
- ans = min(ans, dfs(l, i) + dfs(i + 1, r));
- return f[l][r] = ans;
- }
- int main() {
- open_file("zuma");
- ios::sync_with_stdio(0);
- cin >> n;
- for (int i = 1; i <= n; ++i)
- cin >> s[i];
- cout << dfs(1, n);
- return 0;
- }
------------------------------------------------------------------------------
(7.17)其实这道题是可以直接递推的,阶段按照区间长度由短到长推进。(好像更好写……老师的话不能全信)
- #include <cstdio>
- #include <iostream>
- #include <cstring>
- #define maxn 510
- using namespace std;
- void open_file(string s) {
- string In = s + ".in", Out = s + ".out";
- freopen(In.c_str(), "r", stdin);
- freopen(Out.c_str(), "w", stdout);
- }
- int f[maxn][maxn], s[maxn], n;
- void dp() {
- memset(f, 0x3f, sizeof(f));
- for (int i = 1; i <= n; ++i)
- f[i][i] = 1;
- for (int k = 2; k <= n; ++k)
- for (int l = 1, r = k; r <= n; ++l, ++r) {
- bool flag = 1;
- for (int i = l; i <= (l + r) >> 1; ++i)
- if (s[i] != s[r - i + l]) flag = false;
- if (flag) {
- f[l][r] = 1;
- continue;
- }
- if (s[l] == s[r])
- f[l][r] = f[l + 1][r - 1];
- for (int i = l; i < r; ++i)
- f[l][r] = min(f[l][r], f[l][i] + f[i + 1][r]);
- }
- }
- int main() {
- open_file("zuma");
- ios::sync_with_stdio(0);
- cin >> n;
- for (int i = 1; i <= n; ++i)
- cin >> s[i];
- dp();
- cout << f[1][n];
- return 0;
- }
话说这个题的文件打开方式是从luogu学来的,整理成了一个接受文件名的函数。
【CF607B】Zuma——区间dp(记忆化搜索/递推)的更多相关文章
- (区间dp + 记忆化搜索)Treats for the Cows (POJ 3186)
http://poj.org/problem?id=3186 Description FJ has purchased N (1 <= N <= 2000) yummy treats ...
- UVA 10003 Cutting Sticks 区间DP+记忆化搜索
UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的 ...
- uva 10891 区间dp+记忆化搜索
https://vjudge.net/problem/UVA-10891 给定一个序列x,A和B依次取数,规则是每次只能从头或者尾部取走若干个数,A和B采取的策略使得自己取出的数尽量和最大,A是先手, ...
- [每日一题2020.06.14]leetcode #70 爬楼梯 斐波那契数列 记忆化搜索 递推通项公式
题目链接 题意 : 求斐波那契数列第n项 很简单一道题, 写它是因为想水一篇博客 勾起了我的回忆 首先, 求斐波那契数列, 一定 不 要 用 递归 ! 依稀记得当年校赛, 我在第一题交了20发超时, ...
- Ural 1183 Brackets Sequence(区间DP+记忆化搜索)
题目地址:Ural 1183 最终把这题给A了.. .拖拉了好长时间,.. 自己想还是想不出来,正好紫书上有这题. d[i][j]为输入序列从下标i到下标j最少须要加多少括号才干成为合法序列.0< ...
- loj 1031(区间dp+记忆化搜索)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1031 思路:dp[i][j]表示从区间i-j中能取得的最大值,然后就是枚举分割点了. ...
- BZOJ1055[HAOI2008]玩具取名 【区间dp + 记忆化搜索】
题目 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后 他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够 ...
- HDU 2517 / POJ 1191 棋盘分割 区间DP / 记忆化搜索
题目链接: 黑书 P116 HDU 2157 棋盘分割 POJ 1191 棋盘分割 分析: 枚举所有可能的切割方法. 但如果用递归的方法要加上记忆搜索, 不能会超时... 代码: #include& ...
- hdu 4597 Play Game(区间dp,记忆化搜索)
Problem Description Alice and Bob are playing a game. There are two piles of cards. There are N card ...
随机推荐
- 【转】Setting up SDL on Windows
FROM: http://lazyfoo.net/tutorials/SDL/01_hello_SDL/windows/index.php Setting up SDL on Windows Last ...
- eyoucms破解授权/去版权插件
插件描述:eyoucms内容管理系统的授权破解,可以去版权的插件,需要请自行关注. https://hbh.cool/find/136.html
- Jumpserver简介,部署使用
Jumpserver简介 Jumpserver 是一款使用 Python, Django 开发的开源跳板机系统, 为亏联网企业提供了认证,授权,审计,自动化运维等功能,基于ssh协议来管理,客户端无需 ...
- 力扣 - 768. 最多能完成排序的块II
目录 题目 思路 代码实现 复杂度分析 题目 这个问题和"最多能完成排序的块"相似,但给定数组中的元素可以重复,输入数组最大长度为2000,其中的元素最大为10**8. arr是一 ...
- js 自适应手机电脑 轮播图
自己写了一个javascript的可循环轮播图,支持手机滑动,不过代码着实小白,全局变量,函数调用满天飞,研究别的代码规范好的轮播图插件,表示看得懂但是写不出.. HTML: <div id=& ...
- PHP修改css文件中的背景图片并下载到本地
扒网站当中一般css中的图片扒不下来,这个脚本就是用来下载这些图片到本地的 流程 1.获取css文件路径 2.打开文件逐行读取判断是否包含需要的图片 2.1 包含则 -进行截取直接获取到相对路径 2. ...
- 搞微服务用阿里开源的 Nacos 真香啊!
本文适合有 Java 基础知识的人群 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>系列,今天给大家带来一款开源 Java 版可以实现动态服务发现, ...
- 【笔记】nrf52832广播使用--厂商自定义数据应用
需求: 1)使用蓝牙不停发送ble广播,发送自定义的数据,并每一秒更新自定义数据. 2)设置不同的发射功率.广播间隔.广播名称 1.初始化 使用nordic官方sdk17版本,打开一个ble串口用例. ...
- 内网渗透 day13-漏洞复现
漏洞复现 目录 1. 永恒之蓝(445端口) 2. 手动微笑漏洞(21端口 vsftpd2.3.4版本) 3. ingres数据库DBMS后门(1524端口) 4. distcc漏洞(3632) 5. ...
- JavaScript变量污染
定义过多的全局变量,有可能造成全局变量冲突,这种现象称为变量污染. 全局变量在全局作用域内外都是可见的.若是已经声明了一个全局变量,再以相同的关键字和标识符重新声明全局变量,后者的赋值会替代前者的赋值 ...