洛谷 P4302 【[SCOI2003]字符串折叠】
又来填一个以前很久很久以前挖的坑
首先如果先抛开折叠的内部情况不谈,我们可以得到这样的一个经典的区间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]字符串折叠】的更多相关文章
- 洛谷P4302 [SCOI2003]字符串折叠(区间dp)
题意 题目链接 Sol 裸的区间dp. 转移的时候枚举一下断点.然后判断一下区间内的字符串是否循环即可 `cpp #include<bits/stdc++.h> #define Pair ...
- 洛谷P4302 [SCOI]字符串折叠 [字符串,区间DP]
题目传送门 字符串折叠 题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS…S(X个S). 如 ...
- P4302 [SCOI2003]字符串折叠
题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS…S(X个S). 如果A = A’, B = ...
- luogu P4302 [SCOI2003]字符串折叠
题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS-S(X个S). 如果A = A', B = ...
- [SCOI2003]字符串折叠(区间dp)
P4302 [SCOI2003]字符串折叠 题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS ...
- 【BZOJ1090】[SCOI2003]字符串折叠(动态规划)
[BZOJ1090][SCOI2003]字符串折叠(动态规划) 题面 BZOJ 洛谷 题解 区间\(dp\).设\(f[i][j]\)表示压缩\([i,j]\)区间的最小长度.显然可以枚举端点转移.再 ...
- 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 ...
- BZOJ 1090: [SCOI2003]字符串折叠 区间DP
1090: [SCOI2003]字符串折叠 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- 【bzoj1090】 [SCOI2003]字符串折叠
[bzoj1090] [SCOI2003]字符串折叠 2014年3月9日3,1140 Description 折叠的定义如下: 1. 一个字符串可以看成它自身的折叠.记作S S 2. X(S)是X ...
- [bzoj1090][SCOI2003]字符串折叠_区间dp
字符串折叠 bzoj-1090 SCOI-2003 题目大意:我说不明白...链接 注释:自己看 想法:动态规划 状态:dp[i][j]表示从第i个字符到第j个字符折叠后的最短长度. 转移:dp[l] ...
随机推荐
- SpringBoot实现全文搜索
• 全文搜索 • solr安装 • solr中文分词 • solr数据库导入 • solr数据查询 • solrj接口调用 1:
- FT 软件项目管理
FT 软件项目: 以Feature Team形式组织起来的软件研发项目. 项目是临时组织不是长期组织. 人员临时组织起来, 无组织汇报关系.大家需要充分理解和认同项目的目标,通过项目获得技术.经验. ...
- django源码分析 LazySetting对象
一.django中通过LazySetting对象来获取项目的配置,LazySetting对象有什么特性?为什么使用这个对象? LazySetting顾名思义,就是延迟获取配置内容.比如,我们定义了一个 ...
- Mina的IoBuffer改造成Netty的ByteBuff
背景:部标GPS通讯底层全部改造成基于Netty服务器实现的,现将Mina的依赖移除,修改过程中有用到缓冲区的读写.现做了如下修改: 原有基于Mina的IoBuffer对字节读写封装代码如下: pac ...
- hive笔记:复杂数据类型-map结构
map 结构 1. 语法:map(k1,v1,k2,v2,…) 操作类型:map ,map类型的数据可以通过'列名['key']的方式访问 案例: select deductions['Feder ...
- 认识多线程中start和run方法的区别?
一.认识多线程中的 start() 和 run() 1.start(): 先来看看Java API中对于该方法的介绍: 使该线程开始执行:Java 虚拟机调用该线程的 run 方法. 结果是两个线程并 ...
- 【vue】vue全家桶
vue-router(http://router.vuejs.org) vuex(https://vuex.vuejs.org/zh/guide/) vue-resource(https://gith ...
- PuTTY 串口调试,为普通用户增加访问串口设备权限
一般情况下,只有 root 用户可以使用 PuTTY 访问串口设备,如果要为普通用户增加访问串口设备的权限,可按如下步骤进行: (以 Ubuntu 14.04.3 系统为例,第一个串口设备,会被识别为 ...
- ksar、sar及相关内核知识点解析
关键词:sar.sadc.ksar./proc/stat./proc/cpuinfo./proc/meminfo./proc/diskstats. 在之前有简单介绍过sar/ksar,最近在使用中感觉 ...
- TensorRT&Sample&Python[end_to_end_tensorflow_mnist]
本文是基于TensorRT 5.0.2基础上,关于其内部的end_to_end_tensorflow_mnist例子的分析和介绍. 1 引言 假设当前路径为: TensorRT-5.0.2.6/sam ...