洛谷 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] ...
随机推荐
- 性能测试 基于Python结合InfluxDB及Grafana图表实时采集Linux多主机性能数据
基于Python结合InfluxDB及Grafana图表实时采集Linux多主机性能数据 by:授客 QQ:1033553122 实现功能 测试环境 环境搭建 使用前提 使用方法 运行程序 效果展 ...
- Vysor破解助手for Linux and macOS
<Vysor Pro破解助手>提供了Windows下的Vysor破解工具,为了使用Linux及macOS同学的方便,最近整理了Linux及macOS版的Vysor破解助手. Linux版V ...
- 自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral
自动给 Asp.Net Core WebApi 增加 ApiVersionNeutral Intro 新增加一个 Controller 的时候,经常忘记在 Controller 上增加 ApiVers ...
- git rebase 使用详解
rebase 假设你现在基于远程分支"origin",创建一个叫"mywork"的分支. $ git checkout -b mywork origin 现 ...
- C++17剖析:string在Modern C++中的实现
概述 GCC 8.2提供了两个版本的std::string:一个是基于Copy On Write的,另一个直接字符串拷贝的.前者针对C++11以前的,那时候没有移动构造,一切以效率为先,需要使用COW ...
- thinkphp v5.1 开发笔记
一.安装TP5.1 1.使用git安装 <1>下载Tp git clone https://github.com/top-think/think tp5 <2>安装核心库 gi ...
- Hive:ORC File Format存储格式详解
一.定义 ORC File,它的全名是Optimized Row Columnar (ORC) file,其实就是对RCFile做了一些优化. 据官方文档介绍,这种文件格式可以提供一种高效的方法来存储 ...
- day2 and day3 总结-python基础-坚持就是胜利
今日份快捷键学习,pycharm中按CTRL+ALT+L 自动规范化操作,不过和QQ的快捷键会有冲突,建议更改QQ的 知识点: 1.编码 2.while循环 3.运算符 4.数字int 5.布尔值 6 ...
- 前端——HTML
HTML HTML叫做超文本标记语言,是一种制作万维网页面标准语言.相当于定义一套规则,大家都来遵守它,这样浏览器就可以去解释它. 浏览器负责将标签翻译成用户看得懂的格式,呈现给用户. 作为开发者需要 ...
- iOS开发基础-UITableView控件简单介绍
UITableView 继承自 UIScrollView ,用于实现表格数据展示,支持垂直滚动. UITableView 需要一个数据源来显示数据,并向数据源查询一共有多少行数据以及每一行显示什么 ...