Uva-1629 Cake slicing(DP)

来源:互联网 发布:php 扩展 编辑:程序博客网 时间:2024/06/01 20:54

题意:给出一个由大写字母组成的长度为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 1047483647using 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;    }}


0 0
原创粉丝点击