题意:

演队在口试中非常不幸。在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的更多相关文章

  1. URAL 1635 Mnemonics and Palindromes

    URAL 1635 思路:区间dp+贪心,先n^2处理出每段区间是否是回文串,然后贪心地找每一段1到i的最少分割. 代码: #include<bits/stdc++.h> using na ...

  2. 回文串+回溯法 URAL 1635 Mnemonics and Palindromes

    题目传送门 /* 题意:给出一个长为n的仅由小写英文字母组成的字符串,求它的回文串划分的元素的最小个数,并按顺序输出此划分方案 回文串+回溯:dp[i] 表示前i+1个字符(从0开始)最少需要划分的数 ...

  3. Ural 1635 Mnemonics and Palindromes(DP)

    题目地址:space=1&num=1635">Ural 1635 又是输出路径的DP...连着做了好多个了. . 状态转移还是挺简单的.要先预处理出来全部的回文串,tag[i] ...

  4. Codeforces 811C Vladik and Memorable Trip (区间异或最大值) (线性DP)

    <题目链接> 题目大意: 给你n个数,现在让你选一些区间出来,对于每个区间中的每一种数,全部都只能出现在这个区间. 每个区间的价值为该区间不同的数的异或值之和,现在问你这n个数最大的价值是 ...

  5. Java集合(九)哈希冲突及解决哈希冲突的4种方式

    Java集合(九)哈希冲突及解决哈希冲突的4种方式 一.哈希冲突 (一).产生的原因 哈希是通过对数据进行再压缩,提高效率的一种解决方法.但由于通过哈希函数产生的哈希值是有限的,而数据可能比较多,导致 ...

  6. URAL 1635. Mnemonics and Palindromes(DP)

    题目链接 本来用区间DP,3次方的复杂度,T了,看了看题解,降维,直接二次方的复杂度可以解.然后折腾一下输出路径..终于过了. #include <cstring> #include &l ...

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

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

  8. Memcached 笔记与总结(5)Memcached 的普通哈希分布和一致性哈希分布

    普通 Hash 分布算法的 PHP 实现 首先假设有 2 台服务器:127.0.0.1:11211 和 192.168.186.129:11211 当存储的 key 经过对 2 (2 台服务器)取模运 ...

  9. 算法初级面试题05——哈希函数/表、生成多个哈希函数、哈希扩容、利用哈希分流找出大文件的重复内容、设计RandomPool结构、布隆过滤器、一致性哈希、并查集、岛问题

    今天主要讨论:哈希函数.哈希表.布隆过滤器.一致性哈希.并查集的介绍和应用. 题目一 认识哈希函数和哈希表 1.输入无限大 2.输出有限的S集合 3.输入什么就输出什么 4.会发生哈希碰撞 5.会均匀 ...

随机推荐

  1. Redis 设计与实现 10:五大数据类型之有序集合

    有序集合 sorted set (下面我们叫zset 吧) 有两种编码方式:压缩列表 ziplist 和跳表 skiplist. 编码一:ziplist zset 在 ziplist 中,成员(mem ...

  2. leetcode 886. 可能的二分法(DFS,染色,种类并查集)

    题目链接 886. 可能的二分法 题意: 给定一组 N 人(编号为 1, 2, ..., N), 我们想把每个人分进任意大小的两组. 每个人都可能不喜欢其他人,那么他们不应该属于同一组. 形式上,如果 ...

  3. dblink查找对应的目标端session

    v$session试图中process字段代表的是客户端所在机器的进程号 例如我使用toad连接数据库,查询到的process即toad的进程号 SELECT process FROM V$SESSI ...

  4. vue href url地址写法

  5. [Usaco2005 Mar]Out of Hay 干草危机

    题目描述 Bessie 计划调查N (2 <= N <= 2,000)个农场的干草情况,它从1号农场出发.农场之间总共有M (1 <= M <= 10,000)条双向道路,所有 ...

  6. Py基础—变量名,条件循环,空执行,编码,运算符,字符比较,简化写法

    变量名 只能是字母,数字,下划线.数字不能开头,不要和python内置的东西重复.赋予变量名内容:name1 = "shit" 输出变量名内容 print(name1) 条件语句 ...

  7. centos 7.0 ping百度提示:ping: www.baidu.com: Name or service not known

    解决方法一: 添加dns服务器 vi /etc/resolv.conf 在文件中添加如下两行: nameserver 8.8.8.8 nameserver 8.8.4.4 保存退出,重启服务器.之后再 ...

  8. centralized collectors 中心化 采集器

    Fluent Bit https://fluentbit.io/ FluentBit is an open source specialized data collector. It provides ...

  9. 服务降级 托底预案 Nginx中使用Lua脚本检测CPU使用率,当达到阀值时开启限流,让用户排队

    https://mp.weixin.qq.com/s/FZAcQQAKomGEe95kln1HCQ 在京东我们是如何做服务降级的 https://mp.weixin.qq.com/s/FZAcQQAK ...

  10. 3分钟搞懂什么是WPF。

    先推荐下猛哥(刘铁猛)的书籍  <深入浅出WPF>. 一直以来,完美的用户体验是桌面应用程序和Web应用程序中的一大障碍.许多开发人员绞尽脑汁将界面设计得美观炫丽些.互 动感强些,但费了九 ...