CodeForces - 1409F. Subsequences of Length Two dp
题意:给出一个s串和t串,可以修改s串中的字母最多k次,问最后s中最多存在子序列t多少个
dp状态: d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]表示在位置 [ 1 , i ] [1,i] [1,i]上,修改了j次,共出现t[1]字符k次
如果t[1]=t[2],就需要特判,直接把所有能替换的全部替换为t[1],如果用上述dp的话会少情况。
代码:
int n,x,dp[maxn][maxn][maxn],ans=0;
char s[maxn],t[maxn];
int main()
{
scanf("%d%d",&n,&x);
scanf("%s",s+1);
scanf("%s",t+1);
if (t[1]==t[2])
{
int num=0;
rep(i,1,n)if (s[i]==t[1])num++;
int cnt=min(n,num+x);
W(cnt*(cnt-1)/2);
return 0;
}
rep(i,0,n)rep(j,0,x)rep(k,0,n)dp[i][j][k]=-INF;
dp[0][0][0]=0;
rep(i,0,n-1)
{
rep(j,0,x)
{
rep(k,0,i)
{
if (dp[i][j][k]==-INF)continue;
dp[i+1][j][k]=max(dp[i+1][j][k],dp[i][j][k]);//不修改
if (s[i+1]==t[1])dp[i+1][j][k+1]=max(dp[i+1][j][k+1],dp[i][j][k]);//原本就是t[1]
if (s[i+1]==t[2])dp[i+1][j][k]=max(dp[i+1][j][k],dp[i][j][k]+k);//原本就是t[2]
if (j+1<=x)dp[i+1][j+1][k+1]=max(dp[i+1][j+1][k+1],dp[i][j][k]);//修改为t[1]
if (j+1<=x)dp[i+1][j+1][k]=max(dp[i+1][j+1][k],dp[i][j][k]+k);//修改为t[2]
}
}
}
rep(j,0,x)rep(k,0,n)ans=max(ans,dp[n][j][k]);
W(ans);
return 0;
}