Codeforces1409 F. Subsequences of Length Two(dp)

题意:

给定长度为n的串S和长度为2的串T,和一个整数k,
一次操作你可以将S串中任意一个字符修改为其他字符,最多进行k次操作,
问最后S串中最多有多少个子序列T。

数据范围:n<=200,k<=n

解法:

特判一下t[1]=t[2]的情况,这时候贪心的改就行了,把s串中不等于t[1]的修改为t[1].

子序列总数就是每个s串中t[2]字符前面的t[1]数量的和.

对于修改操作,肯定是将字符修改为t[1]或者t[2],其他字符不考虑,
令d[i][j][k]表示s串前i个数,已经修改j次,t[1]有k个时的答案.
开第三维k是因为遇到t[2]的时候,需要知道前面t[1]的数量.

然后dp一下就行了,枚举是否修改以及修改为t[1]还是t[2]进行转移.

code:

#include
using namespace std;
const int maxm=405;
int d[maxm][maxm][maxm];
char s[maxm];
char t[maxm];
int n,x;
signed main(){
     
    cin>>n>>x;
    scanf("%s",s+1);
    scanf("%s",t+1);
    if(t[1]==t[2]){
     //特判两个字符相等的情况
        int cnt=0;
        for(int i=1;i<=n;i++){
     
            if(s[i]==t[1])cnt++;
            else if(x)x--,cnt++;
        }
        cout<<cnt*(cnt-1)/2<<endl;
        return 0;
    }
    //init
    for(int i=0;i<=n;i++){
     
        for(int j=0;j<=x;j++){
     
            for(int k=0;k<=i;k++){
     
                d[i][j][k]=-1e9;
            }
        }
    }
    //dp
    d[0][0][0]=0;
    for(int i=0;i<n;i++){
     
        for(int j=0;j<=i&&j<=x;j++){
     
            for(int k=0;k<=i;k++){
     
                if(d[i][j][k]==-1e9)continue;//非法
                d[i+1][j][k]=max(d[i+1][j][k],d[i][j][k]);//不修改
                if(s[i+1]==t[1]){
     
                    d[i+1][j][k+1]=max(d[i+1][j][k+1],d[i][j][k]);
                }
                if(s[i+1]==t[2]){
     
                    d[i+1][j][k]=max(d[i+1][j][k],d[i][j][k]+k);
                }
                //
                if(j+1<=x){
     //修改为t[1]
                    d[i+1][j+1][k+1]=max(d[i+1][j+1][k+1],d[i][j][k]);
                }
                if(j+1<=x){
     //修改为t[2]
                    d[i+1][j+1][k]=max(d[i+1][j+1][k],d[i][j][k]+k);
                }
            }
        }
    }
    //cal
    int ans=0;
    for(int j=0;j<=x;j++){
     
        for(int k=0;k<=n;k++){
     
            ans=max(ans,d[n][j][k]);
        }
    }
    cout<<ans<<endl;
    return 0;
}

你可能感兴趣的:(Codeforces1409 F. Subsequences of Length Two(dp))