这题直觉上来说可以使用区间dp进行合法状态的转移,然后记录最小值。
现在的问题是这个是个无限长度的串,因此我们可以大胆猜测,只需要其中一部分就能把所有的情况构造出来
经过打表处理后发现,只需要前13个以内就能构造出所有合法状态,因此只需要这样区间dp即可

#include<bits/stdc++.h> #define getsz(p) (p?p->sz:0) using namespace std; typedef long long ll; const int mod=1e9+7; const int N=3e5+10; int f[14][14][5050]; string s="01145141919114514"; int st[N]; int ans[N]; int main(){ ios::sync_with_stdio(false); int t; cin>>t; memset(f,0,sizeof f); int len,i,j,k; int tmp=0; for(i=1;i<13;i++){ tmp=0; for(j=i;j<=(min(12,i+3));j++){ tmp=tmp*10+(s[j]-'0'); if(tmp<=5000) f[i][j][tmp]=1; } } for(len=2;len<13;len++){ for(i=1;i+len-1<13;i++){ int j=i+len-1; for(k=i;k<j;k++){ for(int l=1;l<=5000;l++){ if(!f[i][k][l]) continue; for(int r=1;r<=5000;r++){ if(!f[k+1][j][r]) continue; if(l*r<=5000) f[i][j][r*l]=1; if(l+r<=5000) f[i][j][l+r]=1; } } } } } for(i=1;i<=13;i++){ for(j=1;j<=5000;j++){ if(f[1][i][j]&&(!ans[j])){ ans[j]=i; } } } while(t--){ int n; cin>>n; cout<<(ans[n]?ans[n]:-1)<<endl; } return 0; }