rqnoj-275-FOLDING-记忆化搜索

记忆化搜索很简单,就是用的时候老是想不到~~无奈的感觉~~~

dp[l][r] :l到r这一段中的最小表示方法。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<stdlib.h>
#define INT_MAX 0x7fffffff
#define maxn 101
#define max3(a,b,c) (max(a,b)>c?max(a,b):c)
#define min3(a,b,c) (min(a,b)<c?min(a,b):c)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
string str;
string dp[maxn][maxn];
string s,ss;
string ns(int x)
{
    ss="";
    if(x>=100)ss.push_back(x/100+'0');
    if(x>=10)ss.push_back((x/10)%10+'0');
    if(x>0)ss.push_back(x%10+'0');
    return ss;
}
int pan(int l,int r,int x)
{
    for(int i=l+x;i<=r;i++)
    {
        if(str[i]!=str[i-x])return 0;
    }
    return 1;
}
string dfs(int l,int r)
{
    int t;
    int i;
    if(dp[l][r]!="")return dp[l][r];
    if(l==r)
    {
        dp[l][r].push_back(str[l]);
        return dp[l][r];
    }
    s="";
    for(i=l;i<=r;i++)
    {
        dp[l][r].push_back(str[i]);
    }
    int len=dp[l][r].size();
    int fn;
    for(i=1;i<=len/2;i++)
    {
        if((r-l+1)%i)continue;
        if(!pan(l,r,i))continue;
        t=(r-l+1)/i;
        fn=1;
        if(t>9)fn=2;
        if(t>99)fn=3;
        s=dfs(l,l+i-1);
        if(s.size()+2+fn<dp[l][r].size())
        {
            dp[l][r]=ns(t)+"("+s+")";
        }
    }
    for(i=l;i<r;i++)
    {
        if(dfs(l,i).size()+dfs(i+1,r).size()<dp[l][r].size())
        {
            dp[l][r]=dp[l][i]+dp[i+1][r];
        }
    }
    return dp[l][r];
}
int main()
{
    while(cin>>str)
    {
        for(int i=0;i<101;i++)
        {
            for(int j=0;j<101;j++)dp[i][j]="";
        }
        cout<<dfs(0,str.size()-1)<<endl;
    }
    return 0;
}


你可能感兴趣的:(rqnoj-275-FOLDING-记忆化搜索)