1238. Folding

http://acm.timus.ru/problem.aspx?space=1&num=1238

DP+记忆化搜索

思路不难,关键是最优结果的储存问题,为了编写方便,直接用string储存最优结果

虽然速度慢了一些,不过写起来方便

代码:

#include<iostream>
#include<stack>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<cmath>

using namespace std;

typedef long long ll;
typedef pair<int,int> pp;
const int INF=0x3f3f3f3f;
const int N=103;
string d[N][N];
string s;
char c[]={'0','1','2','3','4','5','6','7','8','9'};
string trans(int k)
{
    string stmp="";
    while(k)
    {
        stmp.insert(stmp.begin(),c[k%10]);
        k=k/10;
    }
    return stmp;
}
bool ok(int l,int r,int x)
{

    for(int i=l+x;i<=r;i++)
    if(s[i]!=s[i-x])
    return false;
    return true;
}
string dp(int l,int r)
{
    if(d[l][r]!="")
    return d[l][r];
    if(l==r)
    {
        d[l][r].push_back(s[l]);
        return d[l][r];
    }
    for(int i=l;i<=r;++i)
    d[l][r].push_back(s[i]);
    string stmp="";
    string st,sx;
    int n=r-l+1;
    for(int i=1;i<=n/2;++i)
    if(n%i==0&&ok(l,r,i))
    {
        int k=n/i;
        st=trans(k);
        sx=dp(l,l+i-1);

        if(st.size()+sx.size()+2<d[l][r].size())
        d[l][r]=st+"("+sx+")";
    }
    for(int i=l;i<r;++i)
    if(dp(l,i).size()+dp(i+1,r).size()<d[l][r].size())
    d[l][r]=dp(l,i)+dp(i+1,r);
    return d[l][r];
}
int main()
{
    //freopen("data.in","r",stdin);
    while(cin>>s)
    {
        for(int i=0;i<N;++i)
        for(int j=0;j<N;++j)
        d[i][j]="";
        cout<<dp(0,s.size()-1)<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/liulangye/p/3347335.html