题目链接

https://www.luogu.org/problemnew/show/P4302

分析

很明显一道区间DP题,对于区间\([l,r]\)的字符串,如果它的字串是最优折叠的,那么它的最优结果要么是所有分割出的字串最优结果之和,要么是在断点处恰好有这个区间的周期串可以进行折叠,折叠后产生的结果

状态转移

 for(ri len=2;len<=n;len++){//枚举长度,套路
for(l=1;l<=n-len+1;l++){
r=l+len-1;
for(ri k=l;k<r;k++){//枚举断点
f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]);//分割出的子串结果之和
x=check(l,k,r);////[k+1,rr]能否由[l,k]的串循环而成
if(x!=-1){//如果能
f[l][r]=min(f[l][r],f[l][k]+2+x);//显而易见的转移
}
}
}
}

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cctype>
#define ll long long
#define ri register int
using std::min;
using std::max;
using std::swap;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;return ;
}
const int maxn=205;
int n,m,f[maxn][maxn];
char s[maxn];
inline int check(int l,int r,int rr){//[r+1,rr]能否由[l,r]的串循环而成
int x,st,len1=r-l+1,len2=rr-l+1;
if(len2%len1)return -1;
x=len2/len1;
for(ri i=1;i<=x;i++){
st=l+(i-1)*len1;
for(ri j=0;j<len1;j++) if(s[l+j]!=s[st+j]) return -1;
}
int cnt=0;
while(x){x/=10;cnt++;}
return cnt;
}
int main(){
int l,r,x;
scanf("%s",s+1); n=strlen(s+1);
for(ri i=0;i<=n;i++)
for(ri j=i;j<=n;j++) f[i][j]=j-i+1;
for(ri len=2;len<=n;len++){
for(l=1;l<=n-len+1;l++){
r=l+len-1;
for(ri k=l;k<r;k++){//枚举断点
f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]);//分割出的子串结果之和
x=check(l,k,r);//能否成为周期串
if(x!=-1){
f[l][r]=min(f[l][r],f[l][k]+2+x);
}
}
}
}
printf("%d\n",f[1][n]);
return 0;
}

luogu4302字符串折叠题解--区间DP的更多相关文章

  1. bzoj 1090 [SCOI2003]字符串折叠(区间DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1090 [题意] 给定一个字符串,问将字符串折叠后的最小长度. [思路] 设f[i][j ...

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

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

  3. [luogu1090 SCOI2003] 字符串折叠(区间DP+hash)

    传送门 Solution 区间DP,枚举断点,对于一个区间,枚举折叠长度,用hash暴力判断是否能折叠即可 Code #include <cstdio> #include <cstr ...

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

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

  5. 1090. [SCOI2003]字符串折叠【区间DP】

    Description 折叠的定义如下: 1. 一个字符串可以看成它自身的折叠.记作S  S 2. X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S)  SSSS…S(X个S). ...

  6. bzoj 1090: [SCOI2003]字符串折叠【区间dp】

    设f[i][j]为区间(i,j)的最短长度,然后转移的话一个是f[i][j]=min(j-i+1,f[i][k]+f[k+1][j]),还有就是把(k+1,j)合并到(i,k)上,需要判断一下字符串相 ...

  7. Blocks题解(区间dp)

    Blocks题解 区间dp 阅读体验...https://zybuluo.com/Junlier/note/1289712 很好的一道区间dp的题目(别问我怎么想到的) dp状态 其实这个题最难的地方 ...

  8. BZOJ 1090 字符串折叠(Hash + DP)

    题目链接 字符串折叠 区间DP.$f[l][r]$为字符串在区间l到r的最小值 正常情况下 $f[l][r] = min(f[l][r], f[l][l+k-1]+f[l+k][r]);$ 当$l$到 ...

  9. hdu 4632 子字符串统计的区间dp

    题意:查找这样的子回文字符串(未必连续,但是有从左向右的顺序)个数. 简单的区间dp,哎,以为很神奇的东西,其实也是dp,只是参数改为区间,没做过此类型的题,想不到用dp,以后就 知道了,若已经知道[ ...

随机推荐

  1. Resend a Request by fiddler

    Resend a Request You can resend a request directly from the Sessions List, or save requests to resen ...

  2. Flutter移动电商实战 --(26)列表页_使用Provide控制子类-2

    主要实现功能,点击一级分类,二级分类跟着变.这里主要用我们的provide 新建provide provide文件夹下创建:child_category.dart 事件上就是这个实体:BxMallSu ...

  3. mysql查询表里的重复数据方法

    select username,count(*) as count from hk_test group by username having count>1;

  4. php中如何传递Session ID

    一般通过在各个页面之间传递的唯一的 Session ID,并通过 Session ID 提取这个用户在服务器中保存的 Session 变量,来跟踪一个用户.常见的 Session ID 传送方法主要有 ...

  5. c++ vector容器自增长

    #include <iostream>#include <vector> using namespace std; int main(){ vector<int> ...

  6. pip使用笔记

    例子: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -U funcat -i: 指定库的安装源 -U:升级 原来已经安装的包,不带U ...

  7. 推荐一个加载动图的网站loading.io

    推荐一个非常好玩的loading gif的资源网站:https://loading.io/ 里面有各种loading的动图.

  8. 78 leetCode 位运算解法

    按照自己的理解题目,数组内所有的组合:假如[1,2,3,4]看成1111到0000里面的排列组合,取位运算. vector<vector > subsets(vector&nums ...

  9. 修改阿里源为Ubuntu 18.04默认的源

    步骤如下: Step1:备份/etc/apt/sources.list sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak Step2:在/ ...

  10. vue首页组件切换

    结构如下 代码如下: <template> <div id="page"> <div style="width: 100%" cl ...