URAL - 1635 哈希区间(或者不哈希)+dp
题意:
演队在口试中非常不幸。在42道考题中,他恰好没有准备最后一道题,而刚好被问到的正是那道题。演队坐在教授面前,一句话也说不出来。但教授心情很好,给了演队最后一次通过考试的机会。他让这个可怜的学生说出考试要考的科目。不幸的是,演队想不起这个科目名字,尽管他记得科目里有诸如安全、程序、设备、可能还有信息学……
Input
输入一行字符串表示为这门课的名字。这是由小写英文字母组成的非空行。这一行的长度最多是4000个字符。
Output
第一行输出可以分解科目名称的最小的回文字符串数目。在第二行输出回文所有的回文字符串,由空格分隔。如果有几个答案是可能的,输出其中任何一个。
Input
pasoib
Output
6
p a s o i b
Input
zzzqxx
Output
3
zzz q xx
Input
wasitacatisaw
Output
1
wasitacatisaw
题解:
可以对每一个区间[l,r]用哈希赋一个唯一的值,对区间[l,r]正序哈希一个值,逆序哈希一个值。那么如果区间[l,r]是回文串,那么这个区间的正序哈希值应该等于逆序哈希值
dp[i]=min(dp[j-1]+1,dp[i])
,dp[i]代表从1-i
区间的回文序列数量
这个状态转移方程就是当区间[j,i]是回文串的时候
如果不会哈希,也可以用一个二维数组来记录一下区间[l,r]是不是回文串,判断回文串就用while循环(这种方法见代码2)
代码1:
- 1 #include<stdio.h>
- 2 #include<string.h>
- 3 #include<iostream>
- 4 #include<algorithm>
- 5 #include<queue>
- 6 #include<vector>
- 7 #include<map>
- 8 #define mem(a,x) memset(a,x,sizeof(a))
- 9 using namespace std;
- 10 const int INF=0x3f3f3f3f;
- 11 const int maxn=4005;
- 12 const int mod=1000000009;
- 13 const int base=13333;
- 14 typedef long long ll;
- 15 ll dp[maxn];//从1--i中回文串的最少个数
- 16 ll h1[maxn],h2[maxn],p[maxn],n;
- 17 ll pre[maxn];
- 18 char s[maxn];
- 19 string str[maxn];
- 20 //找出来[l,r]这个区间正序的哈希值
- 21 ll get1(ll l,ll r)
- 22 {
- 23 return h1[r]-h1[l-1]*p[r-l+1];
- 24 }
- 25 //找出来[l,r]这个区间倒序的哈希值
- 26 ll get2(ll l,ll r)
- 27 {
- 28 return h2[r]-h2[l-1]*p[r-l+1];
- 29 }
- 30 //如果区间[l,r]的正序逆序哈希值一样,那么这个区间就是回文串
- 31 bool check(ll i,ll j)
- 32 {
- 33 if(get1(i,j)==get2(n-j+1,n-i+1))
- 34 return true;
- 35 return false;
- 36 }
- 37 int main()
- 38 {
- 39 ios::sync_with_stdio(false);
- 40 cin.tie(0);
- 41 memset(dp,INF,sizeof dp);
- 42 dp[0]=0;
- 43 cin>>(s+1);
- 44 n=strlen(s+1);
- 45 p[0]=1;
- 46 for(ll i=1; i<=n; i++)
- 47 {
- 48 h1[i]=h1[i-1]*base-s[i]-'a'+1;
- 49 h2[i]=h2[i-1]*base-s[n+1-i]-'a'+1;
- 50 p[i]=p[i-1]*base;
- 51 }
- 52 for(ll i=1; i<=n; i++)
- 53 {
- 54 for(ll j=1; j<=i; j++)
- 55 {
- 56 if(check(j,i))
- 57 {
- 58 if(dp[i]>(dp[j-1]+1))
- 59 {
- 60 pre[i]=j; //记录路径
- 61 dp[i]=dp[j-1]+1;
- 62 }
- 63 }
- 64 }
- 65 }
- 66 cout<<dp[n]<<endl;
- 67 int id=0;
- 68 int now=n;
- 69 while(now)
- 70 {
- 71 for(int i=pre[now]; i<=now; i++)
- 72 str[id]+=s[i]; //str串记录回文串
- 73 now=pre[now]-1;
- 74 id++;
- 75 }
- 76 for(int i=id-1; i>=0; i--)
- 77 {
- 78 if(i!=0)
- 79 cout<<str[i]<<' ';
- 80 else
- 81 cout<<str[i]<<endl;
- 82 }
- 83 }
代码2:(参考:https://blog.csdn.net/zmx354/article/details/20078995)
- 1 #include <iostream>
- 2
- 3 #include <algorithm>
- 4
- 5 #include <cstdlib>
- 6
- 7 #include <cstdio>
- 8
- 9 #include <cstring>
- 10
- 11 #include <queue>
- 12
- 13 #include <cmath>
- 14
- 15 #include <stack>
- 16
- 17
- 18
- 19 #pragma comment(linker, "/STACK:1024000000");
- 20
- 21 #define LL long long int
- 22
- 23 #define ULL unsigned long long int
- 24
- 25 #define _LL __int64
- 26
- 27 #define INF 0x3f3f3f3f
- 28
- 29 #define Mod 1000000009
- 30
- 31
- 32
- 33 using namespace std;
- 34
- 35
- 36
- 37 char s[4010];
- 38
- 39
- 40
- 41 bool dp[4001][4001];
- 42
- 43
- 44
- 45 int ans[4010];
- 46
- 47
- 48
- 49 int di[4010];
- 50
- 51
- 52
- 53 void Output(int l)
- 54
- 55 {
- 56
- 57 if(l == 0)
- 58
- 59 return ;
- 60
- 61
- 62
- 63 Output(di[l]);
- 64
- 65
- 66
- 67 if(di[l] != 0)
- 68
- 69 printf(" ");
- 70
- 71
- 72
- 73 for(int i = di[l]+1;i <= l; ++i)
- 74
- 75 {
- 76
- 77 printf("%c",s[i]);
- 78
- 79 }
- 80
- 81 }
- 82
- 83
- 84
- 85 int main()
- 86
- 87 {
- 88
- 89 int l,i,j,h,e;
- 90
- 91
- 92
- 93 scanf("%s",s+1);
- 94
- 95
- 96
- 97 l = strlen(s+1);
- 98
- 99
- 100
- 101 memset(dp,false,sizeof(dp));
- 102
- 103
- 104
- 105 for(i = 1;i <= l; ++i)
- 106
- 107 {
- 108
- 109 dp[i][i] = true;
- 110
- 111 h = i-1;
- 112
- 113 e = i+1;
- 114
- 115
- 116
- 117 while(1 <= h && e <= l && s[h] == s[e])
- 118
- 119 {
- 120
- 121 dp[h][e] = true;
- 122
- 123 h--,e++;
- 124
- 125 }
- 126
- 127
- 128
- 129 h = i,e = i+1;
- 130
- 131
- 132
- 133 while(1 <= h && e <= l && s[h] == s[e])
- 134
- 135 {
- 136
- 137 dp[h][e] = true;
- 138
- 139 h--,e++;
- 140
- 141 }
- 142
- 143 }
- 144
- 145
- 146
- 147 memset(ans,INF,sizeof(ans));
- 148
- 149
- 150
- 151 ans[0] = 0;
- 152
- 153
- 154
- 155 di[1] = 0;
- 156
- 157
- 158
- 159 for(i = 1;i <= l; ++i)
- 160
- 161 {
- 162
- 163 for(j = i;j >= 1; --j)
- 164
- 165 {
- 166
- 167 if(dp[j][i])
- 168
- 169 {
- 170
- 171 if(ans[i] > ans[j-1]+1)
- 172
- 173 {
- 174
- 175 ans[i] = ans[j-1]+1;
- 176
- 177 di[i] = j-1;
- 178
- 179 }
- 180
- 181 }
- 182
- 183 }
- 184
- 185 }
- 186
- 187
- 188
- 189 printf("%d\n",ans[l]);
- 190
- 191
- 192
- 193 Output(l);
- 194
- 195
- 196
- 197 puts("");
- 198
- 199
- 200
- 201 return 0;
- 202
- 203 }
URAL - 1635 哈希区间(或者不哈希)+dp的更多相关文章
- URAL 1635 Mnemonics and Palindromes
URAL 1635 思路:区间dp+贪心,先n^2处理出每段区间是否是回文串,然后贪心地找每一段1到i的最少分割. 代码: #include<bits/stdc++.h> using na ...
- 回文串+回溯法 URAL 1635 Mnemonics and Palindromes
题目传送门 /* 题意:给出一个长为n的仅由小写英文字母组成的字符串,求它的回文串划分的元素的最小个数,并按顺序输出此划分方案 回文串+回溯:dp[i] 表示前i+1个字符(从0开始)最少需要划分的数 ...
- Ural 1635 Mnemonics and Palindromes(DP)
题目地址:space=1&num=1635">Ural 1635 又是输出路径的DP...连着做了好多个了. . 状态转移还是挺简单的.要先预处理出来全部的回文串,tag[i] ...
- Codeforces 811C Vladik and Memorable Trip (区间异或最大值) (线性DP)
<题目链接> 题目大意: 给你n个数,现在让你选一些区间出来,对于每个区间中的每一种数,全部都只能出现在这个区间. 每个区间的价值为该区间不同的数的异或值之和,现在问你这n个数最大的价值是 ...
- Java集合(九)哈希冲突及解决哈希冲突的4种方式
Java集合(九)哈希冲突及解决哈希冲突的4种方式 一.哈希冲突 (一).产生的原因 哈希是通过对数据进行再压缩,提高效率的一种解决方法.但由于通过哈希函数产生的哈希值是有限的,而数据可能比较多,导致 ...
- URAL 1635. Mnemonics and Palindromes(DP)
题目链接 本来用区间DP,3次方的复杂度,T了,看了看题解,降维,直接二次方的复杂度可以解.然后折腾一下输出路径..终于过了. #include <cstring> #include &l ...
- Ural 1183 Brackets Sequence(区间DP+记忆化搜索)
题目地址:Ural 1183 最终把这题给A了.. .拖拉了好长时间,.. 自己想还是想不出来,正好紫书上有这题. d[i][j]为输入序列从下标i到下标j最少须要加多少括号才干成为合法序列.0< ...
- Memcached 笔记与总结(5)Memcached 的普通哈希分布和一致性哈希分布
普通 Hash 分布算法的 PHP 实现 首先假设有 2 台服务器:127.0.0.1:11211 和 192.168.186.129:11211 当存储的 key 经过对 2 (2 台服务器)取模运 ...
- 算法初级面试题05——哈希函数/表、生成多个哈希函数、哈希扩容、利用哈希分流找出大文件的重复内容、设计RandomPool结构、布隆过滤器、一致性哈希、并查集、岛问题
今天主要讨论:哈希函数.哈希表.布隆过滤器.一致性哈希.并查集的介绍和应用. 题目一 认识哈希函数和哈希表 1.输入无限大 2.输出有限的S集合 3.输入什么就输出什么 4.会发生哈希碰撞 5.会均匀 ...
随机推荐
- /var/lib/zabbix/percona/scripts/get_mysql_stats_wrapper.sh: line 19: mysql: command not found
[root@test ~]# tail -f /tmp/zabbix_agentd.log /var/lib/zabbix/percona/scripts/get_mysql_stats_wrappe ...
- 【设计模式】Java设计模式精讲之原型模式
简单记录 - 慕课网 Java设计模式精讲 Debug方式+内存分析 & 设计模式之禅-秦小波 文章目录 1.原型模式的定义 原型-定义 原型-类型 2.原型模式的实现 原型模式的通用类图 原 ...
- 【MySql】[ERROR] Can't read from messagefile '/usr/share/mysql/english/errmsg.sys'
[root@zhang bin]# ./mysql_install_db --datadir=/usr/local/mysql/mydata/data/ 2018-08-18 03:09:14 [WA ...
- 【EXP】WINDOWS下如何导出
有些时候需要在windows下通过远程来导出数据 那么windows下怎么导出呢 例子: exp hr/hr@192.168.1.222:1521/zhang file=d:backup.dmp lo ...
- 【Oracle】Oracle 10g下载路径
ORACLE 10g下载地址 下载方法: 直接复制下面的链接,打开迅雷,自动会识别下载的内容 Oracle Database 10g Release 2 (10.2.0.1.0) Enterprise ...
- 使用SimpleUpdater实现现有程序升级功能
项目:https://github.com/iccfish/FSLib.App.SimpleUpdater C/S程式一般需要部署在多台机器上,如果程式有变动,需要一台一台重新安装,相当麻烦,如果我们 ...
- 前端基础功能,原生js实现轮播图实例教程
轮播图是前端最基本.最常见的功能,不论web端还是移动端,大平台还是小网站,大多在首页都会放一个轮播图效果.本教程讲解怎么实现一个简单的轮播图效果.学习本教程之前,读者需要具备html和css技能,同 ...
- Docker 建站小记
一,前言 Docker 建站小记,我使用了四个镜像来搭建:nginx,certbot,mysql,gradle.欢迎访问:https://www.zzk0.top 这个网页是从 github 上找的个 ...
- Jmeter-插件扩展及性能监控插件的安装
需要对http服务进行大数据量的传值测试:看看产品中的http服务,能支持传多少字符:目标值是希望能到10w+: 上次测试中,服务器总是内存满导致服务不响应,因此想增加对服务端的性能监控:查阅了smi ...
- C语言中二维数组声明时,探究省略第一维的原因
我们在使用二维数组作为参数时,我们既可以指明这个数组各个维度的维数,同时我们也可以省略一维,但是二维却不能省略.why呢?由于编译器原理的限制,在一个数组Elemtype test[m][n]中,访问 ...