记忆化搜索很简单,就是用的时候老是想不到~~无奈的感觉~~~
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;
}
本文介绍了一种使用记忆化搜索解决字符串压缩问题的方法。通过动态规划思想避免重复计算,达到优化递归算法的目的。文章提供了完整的C++实现代码,包括自定义函数用于数字转字符串及模式匹配验证。

被折叠的 条评论
为什么被折叠?



