P2875 [USACO07FEB] The Cow Lexicon S

· · 题解

这真是道大水题

拿道题之后,觉得这题肯定是动态规划。于是,就开始想状态。

想一想怎么转移。前面的变成牛语的字符串加上一个单词一定是一个合法牛语。所以我们只要看看结尾是哪个单词,然后配对。 ```cpp for (k=i;k>=1;k--) { if (a[k]==b[j][len]) len--; else sum++; if (!len) break; } ``` $sum$ 表示配对失败的个数, 如果配对成功,那么就有 $dp_i=\max(dp_i,dp_{k-1}+sum)$。 $k-1$ 就是配对成功的开头的前一个。最后的结果就是 $dp_n$。 上代码!! - 代码 ```cpp #include<bits/stdc++.h> using namespace std; const int N=310,M=610; int m,n,i,j,k,dp[N],len,sum; char a[N],b[M][N]; int main() { scanf("%d%d%s",&m,&n,a+1); for (i=1;i<=m;i++) scanf("%s",b[i]+1); for (i=1;i<=n;i++) { dp[i]=i; for (j=1;j<=m;j++) { sum=0; len=strlen(b[j]+1); for (k=i;k>=1;k--) { if (a[k]==b[j][len]) len--; else sum++; if (!len) break; } if (k) dp[i]=min(dp[i],dp[k-1]+sum); } } printf("%d",dp[n]); return 0; } ```