码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1090: [SCOI2003]字符串折叠 区间DP

时间:2015-09-08 22:06:28      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:

1090: [SCOI2003]字符串折叠

Time Limit: 1 Sec  

Memory Limit: 256 MB

题目连接

http://www.lydsy.com/JudgeOnline/problem.php?id=1090

Description

折叠的定义如下: 1. 一个字符串可以看成它自身的折叠。记作S ? S 2. X(S)是X(X>1)个S连接在一起的串的折叠。记作X(S) ? SSSS…S(X个S)。 3. 如果A ? A’, B?B’,则AB ? A’B’ 例如,因为3(A) = AAA, 2(B) = BB,所以3(A)C2(B) ? AAACBB,而2(3(A)C)2(B)?AAACAAACBB 给一个字符串,求它的最短折叠。例如AAAAAAAAAABABABCCD的最短折叠为:9(A)3(AB)CCD。

Input

仅一行,即字符串S,长度保证不超过100。

Output

仅一行,即最短的折叠长度。

Sample Input

NEERCYESYESYESNEERCYESYESYES

Sample Output

14

HINT

 

题意

 

题解:

哎呦卧槽,这道题和http://www.cnblogs.com/qscqesze/p/4782156.html这道题一模一样……

双倍经验爽呀!

代码:

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <bitset>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 110000
#define mod 10007
#define eps 1e-9
#define pi 3.1415926
int Num;
//const int inf=0x7fffffff;   //§ß§é§à§é¨f§³
const ll Inf=0x3f3f3f3f3f3f3f3fll;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
//**************************************************************************************

string s[110][110];
int n;
int dp[110][110];
int vis[110][110];
char S[110];
int FF(int x)
{
    int add=0;
    while(x)
    {
        add++;
        x/=10;
    }
    return add;
}
string F(int x)
{
    string ss;
    while(x)
    {
        ss+=(char)(x%10+0);
        x/=10;
    }
    reverse(ss.begin(),ss.end());
    return ss;
}
int solve(int l,int r)
{
    if(vis[l][r])return dp[l][r];
    vis[l][r]=1;
    for(int i=l;i<r;i++)
    {
        if(dp[l][r]>solve(l,i)+solve(i+1,r))
        {
            dp[l][r]=dp[l][i]+dp[i+1][r];
            s[l][r]=s[l][i]+s[i+1][r];
        }
    }
    for(int i=1;i<r-l+1;i++)
    {
        if((r-l+1)%(i)!=0)
            continue;
        int add = 0;
        for(int k=0;;k++)
        {
            if((k+1)*i>r-l+1)
                break;
            for(int j=0;j<i;j++)
            {
                if(S[l+k*i+j]!=S[l+j])
                    break;
                if(j==i-1)
                    add+=1;
            }
        }

        if(add==(r-l+1)/i)
        {
            int point=solve(l,l+i-1)+2+FF(add);
            if(dp[l][r]>point)
            {
                dp[l][r]=point;
                s[l][r]="";
                s[l][r]+=F(add)+(;
                s[l][r]+=s[l][(1)*i-1+l];
                s[l][r]+=);
            }
        }
    }
    return dp[l][r];
}
int main()
{
    scanf("%s",S+1);
    n = strlen(S+1);
    for(int i=1;i<=n;i++)
    {
        for(int j=i;j<=n;j++)
        {
            dp[i][j]=j-i+1;
            for(int k=0;k<j-i+1;k++)
            {
                s[i][j]+=S[i+k];
            }
        }
    }
    solve(1,n);
    cout<<dp[1][n]<<endl;
    return 0;
}

 

BZOJ 1090: [SCOI2003]字符串折叠 区间DP

标签:

原文地址:http://www.cnblogs.com/qscqesze/p/4792943.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!