洛谷 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] ...
随机推荐
- BGP: 容易实现路由备份,不容易实现等价负载均衡。
一.结论: 1.BGP只能建立备份路由,不能建立等价路由. 2.BGP按照下面的规则进行优选路由. BGP选择路由的策略 当到达同一目的地存在多条路由时,BGP依次对比下列属性来选择路由: 优选协议首 ...
- HA总结:AWS 网络连接
单数据中心 网络HA总结 参考:https://d1.awsstatic-china.com/aws-answers/AWS_Single_Data_Center_HA_Network_Connect ...
- PJSUA2开发文档--第十二章 PJSUA2 API 参考手册
12 PJSUA2 API 参考手册 12.1 endpoint.hpp PJSUA2基本代理操作. namespace pj PJSUA2 API在pj命名空间内. 12.1.1 class En ...
- aspnetcoremodule 2.1下载
下载地址 or 云盘 aspnetcoremodule 2.1 页面地址 下载地址 云盘下载 链接:https://pan.baidu.com/s/1YKYzpP7E__yXQKpOVrN6nw 密码 ...
- python之生成随机密码
https://www.cnblogs.com/evablogs/p/7096583.html 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #!/usr/bin/py ...
- Windows10系统无法更新
方法一: 1.先检查一下windows update服务是否开启,并禁用杀毒软件: 2.如果此服务已经启动,先尝试更换一下网络环境重新更新: 3.如果更换网络环境后依然无法更新,就删除windows ...
- Github如何提交修改的代码以及更新到最新版本
最近有人问我,Github上如何把修改fork到的代码提交到原版本上去,以及如何更新到最新的版本.只针对初学者,大神的话勿喷. 首先说第一个问题. 进入到你修改的某个repository里面(以本人的 ...
- python中创建虚拟环境
# virtualenv 虚拟环境安装 pip install virtualenv # 创建虚拟环境 virtualenv [虚拟环境名称] # 进入虚拟环境 windows : 进入 ...
- nginx实现新老网站跳转(原URL不变)
新老网站实现跳转 原URL保持不变 通过手动添加cookie 匹配cookie的方法进行跳转第一步 进行添加if判断条件 if ( $query_string ~* "sr=pro" ...
- LVS负载均衡基础介绍及NET、DR模式配置
LVS:术语: CIP:Client IP:客户端IP: VIP:Virtual Server IP:虚拟主机对外IP: RIP:Real Server IP:真实主机IP: DIP:Director ...