传送门

题意  

思路一

  定义 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. ubuntu上安装notepadpp

    Notepad++是一套非常有特色的自由软件的纯文字编辑器(许可证:GPL).有完整的中文化接口及支持多国语言编写的功能(UTF8 技术).它的功能比 Windows 中的 Notepad(记事本)强 ...

  2. github遇到 non-fast-forward错误

    可以参考:这里 解决过程如图所示

  3. NodeJs的简介及安装

    首先 分享一下NodeJs的应用场景吧: Web聊天室(IM):Express + Socket.io socket.io一个是基于Nodejs架构体系的,支持websocket的协议用于时时通信的一 ...

  4. 安装mongoDB时,总是报错,启动不了

    安装教程地址:https://blog.csdn.net/fengtingyan/article/details/88371232 原文地址:https://blog.csdn.net/qq_2008 ...

  5. Directx11教程(59) tessellation学习(1)

    原文:Directx11教程(59) tessellation学习(1)       在D3D11管线中,新增加了3个stage, Hull shader, Tessellator, Domain s ...

  6. jmeter使用Badboy录制、检查点和参数化

    jmeter使用Badboy录制 1.打开Badboy,在地址栏输入需要录制的网址,如:百度首页

  7. 1-1.go开发工具安装

    (1) (2) bin:go的可执行文件 src:go的源代码 (3)安装开发工具 安装:goland-2018.1.1.exe 将.jar文件复制到工具的bin目录下   用记事本打开“goland ...

  8. AtCoder Regular Contest 084 C - Snuke Festival【二分】

    C - Snuke Festival ....最后想到了,可是不应该枚举a[],这样要二重循环,而应该枚举b[],这样只需一重循环... #include<iostream> #inclu ...

  9. Effective C++: 03资源管理

    所谓资源,就是一旦用了它,将来必须还给系统.C++中的资源有:内存.文件描述符.互斥锁.数据库连接.网络socket等. 13:以对象管理资源 1:像下面这个函数: void f() { Invest ...

  10. Android BroadcastReceiver 简介

    Android BroadcastReceiver 简介  在 Android 中使用 Activity, Service, Broadcast, BroadcastReceiver     活动(A ...