http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1008
如果只有两个字符串的话 就直接用DP记忆化搜索 时间复杂度是 两者长度的乘积
这个题也可以DP记忆化搜索 因为所有字符串的的乘积最大为30000 再加上枚举最优 时间复杂度也不大
只要把n维 翻译成一维就可以记忆化了
不过为了方便 我用了map 来代替记忆化的功能
代码:
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<vector> #include<set> #include<map> #include<string> #include<stack> #include <iomanip> using namespace std; #define LL long long const int INF=0x3f3f3f3f; const int N=105; map<string,int>str; string s[N]; char a[N]; int I; bool OK(string k) { for(unsigned int i=1;i<k.size();++i) if(s[i][k[i]]!=s[i-1][k[i-1]]) return false; return true; } int dp(string k) { map<string,int>:: iterator it; it=str.find(k); if(it!=str.end()) return (it->second); str[k]=0; it=str.find(k); if(OK(k)) { it->second=1; unsigned int i; for(i=0;i<k.size();++i) if(k[i]==0) break; else k[i]=k[i]-1; if(i==k.size()) it->second=it->second+dp(k); }else { for(unsigned int i=0;i<k.size();++i) { if(k[i]>0) { k[i]=k[i]-1; it->second=max(it->second,dp(k)); k[i]=k[i]+1; } } } return (it->second); } int main() { for(int i=0;i<N;++i) a[i]=i; int T; cin>>T; while(T--) { int n; cin>>n; I=0; while(n--) { cin>>s[I]; if(s[I].size()>0) ++I; } string k; for(int i=0;i<I;++i) k.insert(k.end(),a[s[i].size()-1]); str.clear(); cout<<dp(k)<<endl; } return 0; }