zoukankan      html  css  js  c++  java
  • 洛谷 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;
    }
    
    在繁华中沉淀自我,在乱世中静静伫立,一笔一划,雕刻时光。
  • 相关阅读:
    [MacOS]修改Wifi默认共享网段
    [CentOS7]升级OpenSSL至1.1.1
    [Linux]checking for libevent support... configure: error: Unable to use libevent (libevent check failed)
    [CentOS7]team模式切换
    HDU 5416 CBR and tree
    CodeForces 374D Inna and Sequence
    HDU 5981 Guess the number
    题目清单
    HDU 5510 Bazinga
    KMP & AC自动机
  • 原文地址:https://www.cnblogs.com/HenryHuang-Never-Settle/p/10560694.html
Copyright © 2011-2022 走看看