#include<iostream>
#include<queue>
using namespace std;
int n,a[105],ans=1000;
string t,s[105][15];
void f(int i,string ns,int sum){
if(i==n+1){
if(ns==t){
ans=min(ans,sum);
}
return;
}
for(int j=1;j<=a[i];j++){
if(sum+1>=ans){
break;
}
if(t.substr(ns.length(),s[i][j].length())==s[i][j]){
f(i+1,ns+s[i][j],sum+1);
}
}
f(i+1,ns,sum);
}
int main(){
cin>>t>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
for(int j=1;j<=a[i];j++){
cin>>s[i][j];
}
}
f(1,"",0);
cout<<(ans==1000?-1:ans)<<endl;
return 0;
}
简要思路:枚举当前背包拿不拿拿什么,然后递归下一个背包。
使用了最优性(超过最小花费直接结束)与可行性(选的与 t 相同才能用)的剪枝。