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

本文介绍了一种解决字符串回文划分问题的算法,利用动态规划和回溯技术寻找字符串的最小子序列回文划分,同时提供了完整的C++实现代码。

 

题目传送门

 1 /*
 2     题意:给出一个长为n的仅由小写英文字母组成的字符串,求它的回文串划分的元素的最小个数,并按顺序输出此划分方案
 3     回文串+回溯:dp[i] 表示前i+1个字符(从0开始)最少需要划分的数量,最大值是i+1,即单个回文串;
 4         之前设置ok[j][j+i] 判断从j到j+i的字符是否为回文串(注意两个for的顺序,为满足ok[j][j+i] = ok[j+1][j+i-1])
 5         最后枚举找到最优划分点,用pre[i]记录前一个位置,print函数 输出空格
 6 */
 7 #include <cstdio>
 8 #include <iostream>
 9 #include <algorithm>
10 #include <cmath>
11 #include <cstring>
12 using namespace std;
13 
14 const int MAXN = 4e3 + 10;
15 const int INF = 0x3f3f3f3f;
16 int dp[MAXN];
17 int pre[MAXN];
18 bool ok[MAXN][MAXN];
19 char s[MAXN];
20 
21 void print(int p)
22 {
23     if (pre[p] == -1)
24     {
25         for (int i=0; i<=p; ++i)    printf ("%c", s[i]);
26     }
27     else
28     {
29         print (pre[p]);    printf (" ");
30         for (int i=pre[p]+1; i<=p; ++i)    printf ("%c", s[i]);
31     }
32 }
33 
34 void work(void)
35 {
36     int len = strlen (s);
37 
38     for (int i=0; i<len; ++i)
39     {
40         for (int j=0; j+i<len; ++j)
41         {
42             if (i == 0)    ok[j][j+i] = true;
43             else if (i == 1)    ok[j][i+j] = (s[j] == s[j+i]);
44             else if (s[j] == s[j+i])    ok[j][j+i] = ok[j+1][j+i-1];
45         }
46     }
47 
48     for (int i=0; i<len; ++i)
49     {
50         dp[i] = i + 1;    pre[i] = i - 1;
51         if (ok[0][i])    {dp[i] = 1;    pre[i] = -1;    continue;}
52         for (int j=i-1; j>=0; --j)
53         {
54             if (ok[j+1][i])
55             {
56                 if (dp[i] > dp[j] + 1)
57                 {
58                     dp[i] = dp[j] + 1;    pre[i] = j;
59                 }
60             }
61         }
62     }
63 
64     printf ("%d\n", dp[len-1]);
65     print (len-1);    puts ("");
66 }
67 
68 int main(void)        //URAL 1635 Mnemonics and Palindromes
69 {
70     //freopen ("P.in", "r", stdin);
71 
72     while (scanf ("%s", s) == 1)
73     {
74         memset (ok, false, sizeof (ok));
75         memset (dp, 0, sizeof (dp));
76         memset (pre, 0, sizeof (pre));
77 
78         work ();
79     }
80 
81     return 0;
82 }

 

转载于:https://www.cnblogs.com/Running-Time/p/4492493.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值