又来填一个以前很久很久以前挖的坑


首先如果先抛开折叠的内部情况不谈,我们可以得到这样的一个经典的区间DP的式子

\(
f[l][r]=min(f[l][r],f[l][k]+f[k+1][r])(l<=k<=r)
\)

这个式子应该很显然吧

然后我们可以继续来思考,折叠时候的情况,比如\(ABCABCABC\),它能折叠成的最短长度就是\(3(ABC)\)

令\(len\)为区间\([l,r]\)中的循环节,\(cal(i)\)表示数字i是几位数,然后我们就可以得到

\(
f[l][r]=min(f[l][r],f[l][l+len-1]+2+cal((r-l+1)/len)(l<=k<=r)
\)

2是括号位数

这里要注意,由于循环节内部仍然可能被折叠,所以应该是\(f[l][l+len-1]\)

其实还挺简单对吧

然后,本题最重要的一点,就是你判断循环节的时候不要判断错了,这样会死的很惨,因为一般都不会怀疑你是那个地方出了问题,然后,我这里用的是异或来处理

由于本人太蒟蒻,所以用的是记忆化搜索

详见代码

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
char a[200];
int f[200][200];
int cal(int x)
{
int ans=0;
while(x)
{
++ans;
x/=10;
}
return ans;
}
inline bool check(int s, int l, int c)
{
if(l%c) return 0;
for(int i=s+c;i<s+l;++i)
if(a[i]^a[(i-s)%c+s]) return 0;
return 1;
}
int dfs(int l,int r)
{
if(f[l][r]<1e7)
return f[l][r];//记忆化
if(r<=l) return 1;
f[l][r]=r-l+1;
for(int k=l;k<=r;++k)
f[l][r]=min(f[l][r],dfs(l,k)+dfs(k+1,r));
int tmp=(r-l+1)/2;
for(int len=tmp;len>=1;--len)//只有小于等于区间长度才有可能形成循环节
if(check(l,r-l+1,len))
f[l][r]=min(f[l][r],f[l][l+len-1]+2+cal((r-l+1)/len)); return f[l][r];
}
int main()
{
scanf("%s",a+1);
int lena=strlen(a+1);
memset(f,0x3f,sizeof f);
for(int i=1;i<=lena;++i)
f[i][i]=1;
printf("%d",dfs(1,lena));
return 0;
}

洛谷 P4302 【[SCOI2003]字符串折叠】的更多相关文章

  1. 洛谷P4302 [SCOI2003]字符串折叠(区间dp)

    题意 题目链接 Sol 裸的区间dp. 转移的时候枚举一下断点.然后判断一下区间内的字符串是否循环即可 `cpp #include<bits/stdc++.h> #define Pair ...

  2. 洛谷P4302 [SCOI]字符串折叠 [字符串,区间DP]

    题目传送门 字符串折叠 题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS…S(X个S). 如 ...

  3. P4302 [SCOI2003]字符串折叠

    题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS…S(X个S). 如果A = A’, B = ...

  4. luogu P4302 [SCOI2003]字符串折叠

    题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS-S(X个S). 如果A = A', B = ...

  5. [SCOI2003]字符串折叠(区间dp)

    P4302 [SCOI2003]字符串折叠 题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS ...

  6. 【BZOJ1090】[SCOI2003]字符串折叠(动态规划)

    [BZOJ1090][SCOI2003]字符串折叠(动态规划) 题面 BZOJ 洛谷 题解 区间\(dp\).设\(f[i][j]\)表示压缩\([i,j]\)区间的最小长度.显然可以枚举端点转移.再 ...

  7. BZOJ1090: [SCOI2003]字符串折叠

    区间dp. 一种是分段dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); 一种是这一段可以缩写dp[i][j]=min(dp[i][j],dp[i][l]+2+ca ...

  8. BZOJ 1090: [SCOI2003]字符串折叠 区间DP

    1090: [SCOI2003]字符串折叠 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  9. 【bzoj1090】 [SCOI2003]字符串折叠

    [bzoj1090] [SCOI2003]字符串折叠 2014年3月9日3,1140 Description 折叠的定义如下: 1. 一个字符串可以看成它自身的折叠.记作S  S 2. X(S)是X ...

  10. [bzoj1090][SCOI2003]字符串折叠_区间dp

    字符串折叠 bzoj-1090 SCOI-2003 题目大意:我说不明白...链接 注释:自己看 想法:动态规划 状态:dp[i][j]表示从第i个字符到第j个字符折叠后的最短长度. 转移:dp[l] ...

随机推荐

  1. JAVA forname classnotfoundexception 错误

    今日在使用Class.forName方法的时候报了错误: JAVA forname classnotfoundexception 原因是Class.forName(className);里面的clas ...

  2. 解决Linux系统下Mysql数据库中文显示成问号的问题

    当我们将开发好的javaWEB项目部署到linux系统上,操作数据库的时候,会出现中文乱码问题,比如做插入操作,发现添加到数据库的数据中文出现论码,下面就将解决linux下mysql中文乱码问题! 打 ...

  3. 使用Linq的泛型功能

    泛型数据访问类: 业务抽象类使用数据访问类: 业务类继承业务抽象类: 使用业务类:

  4. 【转载】【时序约束学习笔记1】Vivado入门与提高--第12讲 时序分析中的基本概念和术语

    时序分析中的基本概念和术语 Basic concept and Terminology of Timing Analysis 原文标题及网址: [时序约束学习笔记1]Vivado入门与提高--第12讲 ...

  5. 初步了解.net

    一..net和C#是什么关系 .net是一个程序运行的平台,它是c#,vb,F#等程序运行的平台,为这些语言提供基础类库.公共语言运行时(CLR)等相关支持. C#是支持.net的一种编程语言..ne ...

  6. Autofs自动挂载探讨

    Autofs介绍: mount是用来挂载文件系统的,可以在系统启动的时候挂载也可以在系统启动后挂载.对于本地固定设 备,如硬盘可以使用mount挂载:而光盘.软盘.NFS.SMB等文件系统具有动态性, ...

  7. SQL 数据类型

    Microsoft Access.MySQL 以及 SQL Server 所使用的数据类型和范围. Microsoft Access 数据类型 数据类型 描述 存储 Text 用于文本或文本与数字的组 ...

  8. 转://linux下的CPU、内存、IO、网络的压力测试工具与方法介绍

    转载地址:http://wushank.blog.51cto.com/3489095/1585927 一.对CPU进行简单测试: 1.通过bc命令计算特别函数 例:计算圆周率 echo "s ...

  9. Vim配置(python版)

    由于马上将用到django框架,需要有一个好的ide来coding,之前做C的开发时候体会到了vim的强大,所以编写python也决定采用vim. PS:除了vim,一般浏览代码多用atom和subl ...

  10. Hexo + GitEE 搭建、备份、恢复、多终端

    Hexo 是一个快速.简洁且高效的博客框架.Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页. Hexo 是使用的比较多的博客框架了,我也尝试自己搭 ...