Uva-1629 Cake slicing(DP)

题意:给出一个由大写字母组成的长度为n(n <= 100)的串,“折叠”成一个尽量短的串.


分析:f[i][j]表示把i到j这一段压缩后的最小长度,那么f[i][j] = min(f[i][k]+f[k+1][j]),如果[i,j]这一子串存在循环节的话还要处理一下折叠的情况.


#include <bits/stdc++.h>
#define N 100005
#define INF 1047483647
using namespace std;
typedef pair<int,int> pii;
string cho[105][105],str;
int n,vis[105][105],f[105][105],T,Next[105];
int kmp(string s)
{
    int m = s.length();
    memset(Next,0,sizeof(int)*(m+2));
    int now = Next[0] = -1;
    for(int i = 1;i < m;i++)
	{
		while(now >= 0 && s[now+1] != s[i]) now = Next[now];
		if(s[now+1] == s[i]) now++;
		Next[i] = now;
	}
	return (m - 1 - Next[m-1]);
}
void dfs(int l,int r)
{
    if(vis[l][r] == T) return;
    vis[l][r] = T;
    f[l][r] = r-l+1;
    cho[l][r] = str.substr(l-1,r-l+1);
    for(int i = l;i < r;i++)
    {
        dfs(l,i);
        dfs(i+1,r);
        if(f[l][i] + f[i+1][r] < f[l][r])
        {
            f[l][r] = f[l][i] + f[i+1][r];
            cho[l][r] = cho[l][i] + cho[i+1][r];
        }
    }
    int circle = kmp(str.substr(l-1,r-l+1));
    if(circle < r-l+1 && ((r-l+1) % circle == 0))
    {
        int t = (r-l+1)/circle;
        string temp;
        if(t == 100) temp += "100";
        else
        {
            if(t >= 10) temp += char(t/10+'0');
            temp += char(t%10+'0');
        }
        dfs(l,l+circle-1);
        temp += "("+cho[l][l+circle-1]+")";
        if(temp.length() < f[l][r])
        {
            f[l][r] = temp.length();
            cho[l][r] = temp;
        }
    }
}
int main()
{
    while(cin>>str)
    {
        ++T;
        int n = str.length();
        dfs(1,n);
        cout<<cho[1][n]<<endl;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值