双序列动态规划

双序列动态规划

状态定义

往往是f[n][m]的二维状态,n,m为两个序列的长度

状态转移

往往是与f[i][j1],f[i1][j],f[i1][j1]有关

P1140

f[i][j]表示A串[0,i]匹配B串[0,j]所得最大价值

正解

f[i][j]=max(f[i][j1]+table[b[j]][],f[i1][j]+table[a[i]][],f[i1][j1]+table[a[i]][b[j]])

暴力

b[j]与A串匹配f[i][j]=max(f[k1][j1]+table[a[k]][b[j]]+sum[i]sum[k])

否则与空串f[i][j]=f[i][j1]+table[b[j]][]

其中sum[i]表示A串与空串匹配价值的前缀和

求解目标f[n][m]

for(int i=1;i<=n;i++){
	sum[i]=sum[i-1]+t[g(a[i])][g('-')];
}
f[0][0]=0;
for(int i=1;i<=m;i++){
	f[0][i]=f[0][i-1]+t[g(b[i])][g('-')];
	f[i][0]=f[i-1][0]+t[g(a[i])][g('-')];
}
for(int i=1;i<=n;i++){
	for(int j=1;j<=m;j++){
		/*
		f[i][j]=f[i][j-1]+t[g(b[j])][g('-')];
		for(int k=i;k;k--){
			f[i][j]=max(f[i][j],f[k-1][j-1]+t[g(a[k])][g(b[j])]+sum[i]-sum[k]);
		}
		*/
		f[i][j]=max(f[i-1][j-1]+t[g(a[i])][g(b[j])],max(f[i-1][j]+t[g(a[i])][g('-')],f[i][j-1]+t[g(b[j])][g('-')]));
	}
}

P1439

f[i][j]表示A串[0,i]和B串[0,j]的最长公共子序列的长度

如果a[i]==b[j],f[i][j]=f[i1][j1]+1

否则f[i][j]=max(f[i1][j],f[i][j1])

求解目标f[n][m]

P2758

f[i][j]表示将A串[0,i]转化为B串[0,j]的最小代价

如果a[i]==b[j],f[i][j]=f[i1][j1]

否则f[i][j]=min(f[i][j1],f[i1][j],f[i1][j1])+1

求解目标f[n][m]

for(int i=0;i<=n;i++)f[i][0]=i;
for(int i=0;i<=m;i++)f[0][i]=i;
for(int i=1;i<=n;i++){
	for(int j=1;j<=m;j++){
		f[i][j]=min(f[i][j],f[i-1][j]+1);
		f[i][j]=min(f[i][j],f[i][j-1]+1);
		f[i][j]=min(f[i][j],f[i-1][j-1]+1);
		if(a[i]==b[j])f[i][j]=min(f[i][j],f[i-1][j-1]);
	}
}

P2679

f[i][j][k]表示从A串[0,i]中取出k个不重叠子串顺次连接,所形成的新字符串与B串[0,j]相等

若不选a[i]f[i][j][k]=f[i1][j][k]

若选a[i],f[i][j][k]=Sum(f[it][jt][k1])

所以f[i][j][k]=f[i1][j][k]+Sum(f[it][jt][k1])

优化:

sum[i][j][k]=Sum(f[it][jt][k1])

显然,若a[i]==b[j],sum[i][j][k]=sum[i1][j1][k]+f[i1][j1][k1]

否则sum[i][j][k]=0

省略第一维

求解目标f[m][K]

注意取模

for(int i=0;i<=n;i++){
	f[0][0]=1;
}
for(int i=1;i<=n;i++){
	for(int j=m;j>=1;j--){
		for(int k=K;k>=1;k--){
			if(a[i]==b[j])sum[j][k]=(sum[j-1][k]+f[j-1][k-1])%mod;
			else sum[j][k]=0;
			f[j][k]=(f[j][k]+sum[j][k])%mod;
		}
	}
}

acwing30

f[i][j]表示A串[i,n]和B串[j,m]是否匹配

如果b[j]为正常字符或.f[i][j]=f[i+1][j+1]

如果为

复制0个,f[i][j]=f[i][j+2]

否则,f[i][j]=f[i+1][j]

初始化f[n][m]=1

求解目标f[0][0]

class Solution {
public:
    vector<vector<int> >f;
    int n,m;
    bool isMatch(string s, string p) {
        n=s.length(),m=p.length();
        f=vector<vector<int> >(n+1,vector<int>(m+1,-1));
        f[n][m]=1;
        return dp(0,0,s,p);
    }
    int dp(int i,int j,string &s,string &p){
        if(f[i][j]!=-1)return f[i][j];
        if(j==m){
            return f[i][j]=(i==n);
        }
        bool mat=(i<n&&(s[i]==p[j]||p[j]=='.'));
        bool ans=0;
        if(j+1<m&&p[j+1]=='*'){
            ans=dp(i,j+2,s,p)||(mat&&dp(i+1,j,s,p));
        }else{
            ans=mat&&dp(i+1,j+1,s,p);
        }
        return f[i][j]=ans;
    }
};
posted @   wertyuio1  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示