题解abc261G
beauty_son_whm · · 题解
好难的区间DP。
首先发现一个性质,由于所有的
对于这种两串匹配的问题我们有一个经典的
其中
让我们想想
更进一步的,我们可以对所有
所以,
考虑第二种转移,我们区间
所以,
其中
现在
初始状态
乍一看没有什么问题,但是,
1.
2.
3.
4.
首先3号转移肯定第一个做,因为它依赖的区间更小,一定被更新过了。这里我们可以钦定
这里说不太清楚,可以自己意会一下,不懂可以私信我。
#include<bits/stdc++.h>
#define ll long long
#define pc putchar
#define mk make_pair
#define fi first
#define se second
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
inline void write(int x){
if(x==0){pc('0');return ;}
if(x<0)pc('-'),x=-x;
char nnu[25];int top=0;
while(x){nnu[++top]=x%10+'0';x/=10;}
for(int i=top;i;i--) pc(nnu[i]);
return ;
}
string S,T;
int n,m;
int k;
char C[55];
string A[55];
int g[55][55][55][55];
int f[55][55][30];
int dis[30][30];
int dp[55][55];
signed main(){
cin>>S>>T;
n=S.size(),m=T.size();
S='-'+S;T='-'+T;
k=read();
memset(g,0x3f,sizeof(g));
memset(f,0x3f,sizeof(f));
memset(dis,0x3f,sizeof(dis));
for(int i=1;i<=k;i++) cin>>C[i]>>A[i];
for(int i=1;i<=k;i++){
A[i]='-'+A[i];
if((signed)A[i].size()==2){
dis[A[i][1]-'a'][C[i]-'a']=1;
}
}
for(int k=0;k<=25;k++) for(int i=0;i<26;i++) for(int j=0;j<26;j++) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
for(int i=1;i<=m;i++) f[i][i][T[i]-'a']=0;
for(int i=1;i<=m;i++) for(int j=1;j<=k;j++) g[i][i][j][1]=f[i][i][A[i][1]-'a'];
for(int len=1;len<=m;len++){
for(int l=1;l+len-1<=m;l++){
int r=l+len-1;
for(int i=1;i<=k;i++){
for(int j=1;j<(signed)A[i].size();j++){
for(int k=l;k<r;k++){
g[l][r][i][j]=min(g[l][r][i][j],g[l][k][i][j-1]+f[k+1][r][A[i][j]-'a']);
}
}
}
for(int i=1;i<=k;i++) for(int c=0;c<=25;c++) if(C[i]-'a'==c&&A[i].size()>=3) f[l][r][c]=min(f[l][r][c],g[l][r][i][(signed)A[i].size()-1]+1);
for(int tim=0;tim<=25;tim++){
for(int c=0;c<=25;c++){
for(int t=0;t<=25;t++){
f[l][r][c]=min(f[l][r][t]+dis[t][c],f[l][r][c]);
}
}
}
for(int i=1;i<=k;i++) g[l][r][i][1]=f[l][r][A[i][1]-'a'];
}
}
memset(dp,0x3f,sizeof(dp));
dp[0][0]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=0;k<j;k++){
dp[i][j]=min(dp[i-1][k]+f[k+1][j][S[i]-'a'],dp[i][j]);
}
}
}
if(dp[n][m]>=1e9)cout<<-1<<endl;
else cout<<dp[n][m]<<endl;
return 0;
}