传送门

题意  

思路一

  定义 dp[i] 表示 0~i 的最少划分数;

  首先,用马拉车算法求解出回文半径数组;

  对于第 i 个字符 si,遍历 j (0 ≤ j < i),判断以 j 为回文中心的最大回文串是否包含 si

  如果包含,dp[ i ]=min{dp[ i ],dp[2*j-i-1]+1};

Code

 #include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+; char t[maxn];
int r[maxn<<]; struct Manacher
{
char s[maxn<<];
void Init(char *ss,int len)
{
int index=;
s[index++]='#';
for(int i=;i < len;++i)
{
s[index++]=ss[i];
s[index++]='#';
}
s[index]='\0';
}
void mana(char *ss)
{
Init(ss,strlen(ss));
int len=strlen(s);
int R=-;
int C;
for(int i=;i < len;++i)
{
r[i]=R > i ? min(R-i+,r[*C-i]):;
for(;i-r[i] >= && i+r[i] < len && s[i-r[i]] == s[i+r[i]];r[i]++);
if(i+r[i] > R)
{
R=i+r[i]-;
C=i;
}
}
}
}_mana; int dp[maxn];
int Solve()
{
_mana.mana(t); dp[]=;
int len=strlen(t);
for(int i=;i < len;++i)
{
dp[i]=dp[i-]+;
for(int j=;j <= *i;++j)
{ ///t中的第i个字符在预处理后的s数组中的位置为2*i+1
///因为可能由偶回文的情况,所以需要用到'#'
///直接判断在s数组中j的对应的最大回文j+r[j]是否包含2*i+1
///如果包含,再找到2*i+1以j为中心的对称点2*j-(2*i+1)
///判断2*j-(2*i+1)对应于t中的位置的前一个位置(2*j-(2*i+1))/2-1是否在[0,len-1]范围内
///如果在,更新dp[i]
int cur=j+r[j];
int index=(*j-*i-)/-;
if(*i+ < cur)
dp[i]=min(dp[i],+(index >= ? dp[index]:));
}
}
return dp[len-];
}
int main()
{
// freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
int test;
scanf("%d",&test);
while(test--)
{
scanf("%s",t);
printf("%d\n",Solve());
}
return ;
}

思路二(reference from zishu)

  定义dp[ i ]表示0~i划分成的最小回文串的个数,则dp[ i ]=min{d[ j ]+1 | j ≤ i && t[ j+1,....,i ]为回文串};

code

 #include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+; char t[maxn];
char s[maxn<<];
bool isPal[maxn][maxn];
int dp[maxn]; void Init()///O(n^2)预处理出t[i,..,j]是否为回文串
{
int len=strlen(t);
for(int i=;i < len;++i)
for(int j=;j < len;++j)
isPal[i][j]=false;
int index=;
s[index++]='#';
for(int i=;i < len;++i)
{
s[index++]=t[i];
s[index++]='#';
}
s[index]='\0'; for(int i=;i < index;++i)
{
int r=;
while(i-r >= && i+r < index && s[i-r] == s[i+r])
{
if((i-r)&)
isPal[(i-r)/][(i+r)/]=true;
r++;
}
}
} int Solve()
{
Init();
int len=strlen(t);
dp[]=;
for(int i=;i < len;i++)
{
dp[i]=dp[i-]+;
for(int j=;j < i;++j)
if(isPal[j][i])
dp[i]=min(dp[i],+(j > ? dp[j-]:));
}
return dp[len-];
}
int main()
{
// freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
int test;
scanf("%d",&test);
while(test--)
{
scanf("%s",t);
printf("%d\n",Solve());
}
return ;
}

UVA 11584 "Partitioning by Palindromes"(DP+Manacher)的更多相关文章

  1. uva 11584 Partitioning by Palindromes 线性dp

    // uva 11584 Partitioning by Palindromes 线性dp // // 题目意思是将一个字符串划分成尽量少的回文串 // // f[i]表示前i个字符能化成最少的回文串 ...

  2. UVA - 11584 Partitioning by Palindromes[序列DP]

    UVA - 11584 Partitioning by Palindromes We say a sequence of char- acters is a palindrome if it is t ...

  3. UVa 11584 - Partitioning by Palindromes(线性DP + 预处理)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  4. UVA 11584 Partitioning by Palindromes (字符串区间dp)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  5. UVA - 11584 Partitioning by Palindromes(划分成回文串)(dp)

    题意:输入一个由小写字母组成的字符串,你的任务是把它划分成尽量少的回文串,字符串长度不超过1000. 分析: 1.dp[i]为字符0~i划分成的最小回文串的个数. 2.dp[j] = Min(dp[j ...

  6. UVa 11584 Partitioning by Palindromes【DP】

    题意:给出一个字符串,问最少能够划分成多少个回文串 dp[i]表示以第i个字母结束最少能够划分成的回文串的个数 dp[i]=min(dp[i],dp[j]+1)(如果从第j个字母到第i个字母是回文串) ...

  7. 【UVa】Partitioning by Palindromes(dp)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=27&page=sh ...

  8. UVa 11584 Partitioning by Palindromes (简单DP)

    题意:给定一个字符串,求出它最少可分成几个回文串. 析:dp[i] 表示前 i 个字符最少可分成几个回文串,dp[i] = min{ 1 + dp[j-1] | j-i是回文}. 代码如下: #pra ...

  9. 区间DP UVA 11584 Partitioning by Palindromes

    题目传送门 /* 题意:给一个字符串,划分成尽量少的回文串 区间DP:状态转移方程:dp[i] = min (dp[i], dp[j-1] + 1); dp[i] 表示前i个字符划分的最少回文串, 如 ...

随机推荐

  1. Percona XtraBackup 完全及增量备份与恢复的方法

    安装及备份.恢复实现 安装:其最新版的软件可从 http://www.percona.com/software/percona-xtrabackup/ 获得.本文基于CentOS6.x的系统,因此,直 ...

  2. 【JZOJ3885】【长郡NOIP2014模拟10.22】搞笑的代码

    ok 在OI界存在着一位传奇选手--QQ,他总是以风格迥异的搞笑代码受世人围观 某次某道题目的输入是一个排列,他使用了以下伪代码来生成数据 while 序列长度<n do { 随机生成一个整数属 ...

  3. Python2.7下,调用subprocess启动子进程,读取子进程标准输出若干问题

    1:如果调用的子进程也是一个python脚本,则subprocess.Popen中的bufsize=1无效果.也就是说,即使设置了bufsize=1表示进行行缓冲,子进程如果不显示调用sys.stdo ...

  4. LeedCode OJ --- Binary Tree Inorder Traversal

    点击打开题目链接 今天只是写了递归的版本,因为还没想好怎么用迭代来实现,可以写的过程中,有一点是有疑问的,虽然我的代码可以AC. 问题是:主调函数是可以使用子函数中返回的在子函数中定义的vector. ...

  5. 洛谷 P3768 简单的数学题 (莫比乌斯反演)

    题意:求$(\sum_{i=1}^{n}\sum_{j=1}^{n}ijgcd(i,j))mod p$(p为质数,n<=1e10) 很显然,推式子. $\sum_{i=1}^{n}\sum_{j ...

  6. Python学习之路9☞面向对象的程序设计

    一 面向对象的程序设计的由来 见概述:http://www.cnblogs.com/linhaifeng/articles/6428835.html 二 什么是面向对象的程序设计及为什么要有它 面向过 ...

  7. python if elif else 区别

    if data_ori=='医疗': # 医疗 df = pd.read_excel(path_apply + 'apply/YS_ZY_HZSQ_样例.xls', encoding='gbk', e ...

  8. 什么是Hessian协议呢?

    什么是Hessian协议呢? 目前,Web服务技术是解决异构平台系统的集成及互操作问题的主流技术. 它所基于的XML已经是Internet上交换数据的实际标准,基于通用的进程间通信协议和网络传输协议屏 ...

  9. 2019-1-16-win10-uwp-发布的时候-ILC-编译不通过

    title author date CreateTime categories win10 uwp 发布的时候 ILC 编译不通过 lindexi 2019-1-16 20:37:5 +0800 20 ...

  10. 创建我的flask第一个应用(二)

    继上一篇创建我的flask第一个应用(一),继续学习配置flask 在myproject未提供flask默认运行的主程序文件"wsgi.py"或"app.py" ...