题解 洛谷P4302 【[SCOI2003]字符串折叠】
一眼区间\(dp\),但蒟蒻的我还是调了好久\(qwq\)
【状态设置】
设\(f[i][j]\)为子串\([i,j]\)的最短折叠
目标为\(f[1][n]\)
【初始化】
\(1\) 首先对于任意的\(i\)必然存在\(f[i][i]=1\)
然后其他的都初始化为\(INF\)即可
\(2\) 因为最后的字符串可能会出现数字,所以不妨考虑用一个数组\(g[x]\)预处理\(x\)的位数\(qwq\)
【\(dp\)核心】
对于任意的\(f[i][j]\) \((i < j)\)可以有两种得到方式。
分成两段,两段的最短折叠连在一起构成,即左区间\(+\)右区间
自身构成:找子串\([i,j]\)中的一个循环子串,形如 循环节 左括号 子串 右括号。长度即为即循环节位数\(+2+\)子串长度。
第一种方式,套区间\(dp\)的模板,先枚举出\(len\)和\(i\),得到\(j=i+len-1\),再跑一遍\(k\)枚举割点,于是得到:
\]
\]
第二种方式,如果子串\([i,k]\)是子串\([i,j]\)中的一个循环子串,则:
\]
\]
【代码】
#include<bits/stdc++.h>
using namespace std;
const int max_n=100+5;
int n,g[max_n],f[max_n][max_n];
string st;
bool check(int ll,int rr,int len){//判断是否是循环节
for(int i=ll;i<=ll+len-1;i++){
char ch=st[i];
for(int j=i;j<=rr;j+=len){
if(st[j]!=ch)return false;
}
}
return true;
}
int main(){
ios::sync_with_stdio(false);
cin>>st;
n=st.size();st=" "+st;//把字符串变成1~n
for(int i=1;i<=9;i++)g[i]=1;
for(int i=10;i<=99;i++)g[i]=2;
g[100]=3;//g[x]表示x的位数
memset(f,0x3f,sizeof(f));
for(int i=1;i<=n;i++)f[i][i]=1;//初始化f数组
for(int len=1;len<=n;len++){
for(int i=1;i+len-1<=n;i++){
int j=i+len-1;//区间DP模板,得到i和j
for(int k=i;k<j;k++){//枚举哪里切
f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);//第一种情况,左区间+右区间
int l=k-i+1;//第二种情况,先得到循环节的长度
if(len%l)continue;//长度不符
if(check(i,j,l))f[i][j]=min(f[i][j],g[len/l]+2+f[i][k]);//是循环节,那么套公式
}
}
}
cout<<f[1][n]<<"\n";
return 0;
}
\(\operatorname{Update}\) \(\operatorname{On}\) \(\operatorname{2019.08.28}\)
题解 洛谷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]\)区间的最小长度.显然可以枚举端点转移.再 ...
- 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. 一种是分段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 ...
随机推荐
- .Net Core 2.0发布到 CentOS
上一篇 在CentOS 7中 使用 Nginx 反代 .Net Core 中创建的项目是创建的默认项目,现在我们来将我们开发的项目发布到 CentOs 中,反代还是使用 Nginx 1.创建一个 .N ...
- React+antd+less框架搭建步骤,看吧,整的明白儿的
1.node版本 首先你要先看下你的node版本,如果小于10,建议升级到10及以上,因为低版本的 node 在自动创建 react框架时,有配置文件跟10及以上的有比较大的差异,而且需要增加.修改的 ...
- VS2017中使用ObjectARX 2019 wizard的 ArxWizMFCSupport向导出现的bug修复前因后果
VS2017中使用ObjectARX 2019 wizard的 ArxWizMFCSupport向导出现的bug,提示脚本错误. 实际原因类似在arx2012向导的问题,需要修改C:\Program ...
- python sys模块(12)
在python sys模块提供对解释器使用或维护的一些变量的访问,以及与解释器强烈交互的函数!关于sys模块在官网也有详细的介绍:python sys模块官方介绍. 一.sys模块简介 sys.arg ...
- windows10 ubuntu子系统运行docker出现的问题
前一篇笔记记录了安装的过程及错误处理办法,但是在正式使用docker时,却又出现新的问题: “docker: Cannot connect to the Docker daemon at unix:/ ...
- c# 用XmlWriter写xml序列化
using System.Text; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; using ...
- windows server系统打印服务配置
系统环境:windows server 2008 R2 Enterprise Service Pack 1 安装内存:8G 系统类型:64位操作系统 目标:在此系统上开启打印服务,可以添加网络打印机 ...
- 【C++札记】虚继承
由于多重继承产生的二义性引入了类的虚继承,先看下什么是二义性. 类D是类B和类C的派生类,而类B,类C就是继承于类A,当D调用类A中的函数时不知道是类B继承A的,还是类C继承A的,引起了二义性.虚继承 ...
- shell中通过eval执行一个字符串命令
#!/bin/bash echo "Switch Directory : /home/pktgen-2.9.0" dir="/home/pktgen-2.9.0" ...
- 解决跟Docker私有仓库登陆,推送,拉取镜像出现的报错
出现问题:Error response from daemon: Get https://192.168.186.120/v1/users/: dial tcp 192.168.186.120:443 ...