博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Folding
阅读量:6934 次
发布时间:2019-06-27

本文共 2682 字,大约阅读时间需要 8 分钟。

给出一个长度为n的序列\(\{a_i\}\),定义一个收缩的序列变为原序列的方式为

  1. 如果该收缩序列只有一个字符,原序列即该个字符。
  2. 如果一个收缩序列由多个收缩序列,那么分别对各个收缩序列进行解压,即原序列
  3. 如果收缩序列形如\(n(S)\),意为收缩序列S重复n次(注意,n为数字,转化成字符需要占空间),解压即把该序列重复n次。

请找到一个最短的收缩序列,解压后正好为序列\(\{a_i\}\)\(n\leq 100\)

显然问题具有区间划分性,因为几个收缩序列可以组成一个收缩序列,于是可以考虑区间递推,设\(f[i][j]\)表示合并\([i,j]\)后的最短的字符串,(接下来的+为字符串的相加,比较大小为字符串长度的比较,不知道意思查string的用法),首先区间合并性可以

\[f[i][j]=\min_{k=i}^{j-1}\{f[i][k]+f[k+1][j]\}\]

现在来考虑循环节的问题,循环节可以\(O(n^2)\)枚举,但是所有的循环节中必然是最短的循环节最优(感性理解一下),设最短循环节为k,有

\[f[i][j]=\min(f[i][j],to\_string(k)+"("+f[i][k-1]+")")\]

边界:\(f[i][i]=a_i\)

答案:\(f[1][n]\)

参考代码:

string 阶段实现

#include 
#include
#define il inline#define ri registerusing namespace std;string s,dp[101][101],lsy;il string To(int);il int xh(int,int);int main(){ cin>>s; for(int i(1);i<=s.size();++i) dp[i][i].push_back(s[i-1]); for(int i,j(1),k;j<=s.size();++j) for(i=j-1;i;--i){ for(k=i;k
lsy.size()) dp[i][j]=lsy; }k=xh(i,j); if(k){ lsy=To((j-i+1)/k)+"("+dp[i][i+k-1]+")"; if(lsy.size()
>1);++i){ if(len%i)continue; for(j=l;j<=r-i;++j){ if(s[j-1]==s[j+i-1])continue; break; }if(j>r-i)return i; }return 0;}

string dfs实现

#include 
#include
#include
#include
#include
#define il inline#define ri registerusing namespace std;string s,dp[101][101], dfs(int,int);il int cycle(int,int);il string To_string(int);int main(){ cin>>s; for(int i(1);i<=s.size();++i) dp[i][i].push_back(s[i-1]); cout<
<
>1);++i){ if(len%i)continue; for(j=l;j<=r-i;++j){ if(s[j-1]==s[j+i-1])continue; break; }if(j>r-i)return i; }return 0;}string dfs(int l,int r){ if(dp[l][r].size())return dp[l][r]; string lsy; for(int k(l);k

char数组实现

#include 
#include
#include
#define il inline#define ri register#define intmax 0x7fffffffusing namespace std;struct String{ char s[111];int len; il void read(){ scanf("%s",s); len=strlen(s); }}s,dp[101][101],lsy;il int xh(int,int);int main(){ s.read(); for(int i(1);i<=s.len;++i) dp[i][i].s[0]=s.s[i-1], dp[i][i].len=1; for(int i,j(1),k,l;j<=s.len;++j) for(i=j-1;i;--i){ dp[i][j].len=intmax; for(k=i;k
>1);++i){ if(L%i)continue; for(j=l;j<=r-i;++j){ if(s.s[j-1]==s.s[j+i-1])continue; break; }if(j>r-i)return i; }return 0;}

转载于:https://www.cnblogs.com/a1b3c7d9/p/11001525.html

你可能感兴趣的文章
WebSocket 原理
查看>>
按端口终止进程
查看>>
Permutations I & II leetcode
查看>>
[LeetCode/LintCode] Factorial Trailing Zeros
查看>>
iOS病毒XcodeGhost批量检测工具,开源Github(检测ipa文件)
查看>>
npm 加入 TC39 委员会,参与定制 JavaScript 标准
查看>>
centos7.2安装mysql
查看>>
关于 Python
查看>>
AVFoundation学习Demo--拍摄视频
查看>>
阿里云账号注册流程方法(图文教程)
查看>>
亮道智能发布自动驾驶环境感知系统测试验证服务|2019 上海车展 ...
查看>>
ROS_机器人urdf建模仿真实践
查看>>
一碗鸡汤
查看>>
平台篇-58 HBase 平台实践和应用
查看>>
史上最大的实体关系抽取数据集!清华大学自然语言处理团队发布 FewRel ...
查看>>
K8s 1.14 发布了,Release Note 该怎么读?
查看>>
购买阿里云服务器,先试试主机免费试用能抢到不
查看>>
2018-01-11 Antlr4实现数学四则运算
查看>>
Docker 和 Kubernetes 从听过到略懂:给程序员的旋风教程
查看>>
ES6 模块加载export 、import、export default 、import() 语法与区别,笔记总结
查看>>