Partitioning by Palindromes - UVa 11584
例题9-7 划分成回文串(Partitioning by Palindromes, UVa 11584)
#dp #线性dp #字符串回文 #T3
输入一个由小写字母组成的字符串,要求把它划分成尽量少的回文串。输出最少的个数。
如aaadbccb最少可以划分为3个:aaa,d,bccb
输入:
第一行输入一个n表示数据组数
接下来n行每行输入一个字符串s(1<=s<=1000)
输出:
输出一个数表示最少的个数
input
3
aaadbccb
ffgcc
juzi
output
3
3
4`
思路
状态表示: f[i]
是 1~i 中回文串个数
状态计算: f[i] = min(f[i], f[j] + 1 ) if i~j 是一个回文串
所以先用n^2把这个串中的所有回文字串标识出来。
bool is_palindrome(int i, int j)
{
if(i >= j) return true;
if(s[i] != s[j]) return false;
if(st[i][j] == kase) return p[i][j];
st[i][j] = kase;
p[i][j] = is_palindrome(i+1,j-1);
return p[i][j];
}
这里的 st 只是为了确保p数组中的值是当前数据组的情况, 正常的判断回文数也可以给st去掉然后每组数据重置一下p数组就行。建议记下来以后判断回文串除了双指针就用递归整。
代码
const int N = 1e3 + 10;
char s[N];
bool p[N][N];
int st[N][N];
int f[N];
int n, kase = 1;
int ispalind(int i, int j)
{
if (i >= j)
return 1;
if (s[i] != s[j])
return 0;
if (st[i][j] == kase)
return p[i][j];
st[i][j] = kase;
p[i][j] = ispalind(i + 1, j - 1);
return p[i][j];
}
int main()
{
int T;
cin >> T;
while (T--)
{
scanf("%s", s + 1);
n = strlen(s + 1);
f[0] = 0;
for (int i = 1; i <= n; i++)
{
f[i] = i + 1;
for (int j = 0; j < i; j++)
if (ispalind(j + 1, i))
f[i] = min(f[i], f[j] + 1);
}
cout << f[n] << endl;
kase++;
}
return 0;
}
标签:
DP | 线性DP
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现