传送门

题意  

思路一

  定义 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. 【机器学习PAI实战】—— 玩转人工智能之你最喜欢哪个男生?

    摘要: 分类问题是生活中最常遇到的问题之一.普通人在做出选择之前,可能会犹豫不决,但对机器而言,则是唯一必选的问题.我们可以通过算法生成模型去帮助我们快速的做出选择,而且保证误差最小.充足的样本,合适 ...

  2. MSSQL → 01:SQLServer 2008概述及安装

    据库的发展史 在人类诞生以来,就有记录数据的需求,在远古时代就有了结绳记事的故事,而随着科技的进步,我们记录数据的方式也发生了天翻地覆的变化,从效率低.规模小.不能适应信息高速发展的需要的手工或者简单 ...

  3. Jmeter里面的时间单位

    1.线程组里面的时间单位为秒(s),如下图:

  4. 【JZOJ4848】【GDOI2017模拟11.3】永恒的契约

    题目描述 宅邸迅速的燃烧着,必须带贝蒂走出禁书库!凭着感觉,又一次直接找到禁书库的门. "你,是那个人嘛?"400年了,当初圣域建立结界时没有进入圣域,被伤了心的人工精灵贝蒂,与强 ...

  5. 小爬爬6.scrapy回顾和手动请求发送

    1.数据结构回顾 #栈def push(self,item) def pop(self) #队列 def enqueue(self,item) def dequeue(self) #列表 def ad ...

  6. hdu 2844 混合背包【背包dp】

    http://acm.hdu.edu.cn/showproblem.php?pid=2844 题意:有n种纸币面额(a1,a2,...an),每种面额对应有(c1,c2,...cn)张.问这些钱能拼成 ...

  7. @codeforces - 1161F@ Zigzag Game

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 2n 个结点的完全二分图,1~n 在左边,n+1~2n ...

  8. 从零学React Native之07View

    View 组件是React Native最基本的组件.绝大部分其他React Native 组件. View组件的颜色和边框 backgroundColor 键用来指定颜色. RN 0.19版本开始, ...

  9. Code Force 429B Working out【递推dp】

    Summer is coming! It's time for Iahub and Iahubina to work out, as they both want to look hot at the ...

  10. [软考]之软件过程模型I 标签: 总结软考 2015-10-24 11:58 863人阅读 评论(35) 收藏

    做软考题的时候经常碰到软件工程的题,因为这些题有的很相近,容易混淆,所以在这里总结归纳一下. 软件过程模型: 瀑布模型: 瀑布模型是将软件生存周期中的各个活动规定为依线性顺序连接的若干阶段的模型,包括 ...