终于正常一点了-1.11考试-解题报告
T1和T3都是比较可爱的。
T2
DP好题,然而被我用暴力踩标算了...
感觉这种“删掉之后两边拼起来”的题都特别恶心。
看到这个题,容易想到区间DP,但是怎么拼起来呢?
我们可以加一维状态。设
转移:
如果下一位匹配的话,
但是我们可能中间跳过了一段,因为那一段被删除了,于是有:
最后求答案的话,再做一遍背包即可。
signed main()
{
#ifdef M207
freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
#endif
in(n,m,K);
scanf("%s",s+1);
for(ri i=1; i<=m; ++i)
{
static char tc[25];
scanf("%s",tc+1);
ins(tc,strlen(tc+1));
}
mem(g,0x3f);
for(ri i=0; i<=n; ++i) g[i+1][i][0]=0;
for(ri len=1; len<=n; ++len)
for(ri l=1,r=len; r<=n; ++l,++r)
{
for(ri p=l; p<=r; ++p)
if(g[p+1][r][0]<K)
{
int w=s[p]-'a';
for(ri i=0; i<=tot; ++i)
if(tre[i][w]) upd(g[l][r][tre[i][w]],g[l][p-1][i]+g[p+1][r][0]);
}
for(ri k=1; k<=tot; ++k)
if(ed[k]) upd(g[l][r][0],g[l][r][k]+1);
}
mem(f,0x3f);
f[0][0]=0;
for(ri i=1; i<=n; ++i)
for(ri j=0; j<=K; ++j)
{
upd(f[i][j],f[i-1][j]+1);
if(j) upd(f[i][j],f[i][j-1]);
for(ri k=1; k<=i; ++k)
if(j>=g[k][i][0]) upd(f[i][j],f[k-1][j-g[k][i][0]]);
}
out(f[n][K]);
return 0;
}