1 条题解

  • 0
    @ 2026-4-26 9:04:28

    这道题挺水的。

    首先,这道题肯定是一个普及的二维线性 dp。

    dpi,jdp_{i,j}SSii 位与 TTjj 位匹配的方案数。

    初始条件 dp0,0=dpi,0=1dp_{0,0}=dp_{i,0}=1

    然后对于每一位 jj,我们可以选择在前面插入一位来匹配 ii,如果能匹配,还可以选择自己去匹配 ii

    所以如果 SiS_i 能匹配 TjT_j,那么 dpi,j=dpi1,j+dpi1,j1dp_{i,j}=dp_{i-1,j}+dp_{i-1,j-1}

    否则,dpi,j=dpi1,jdp_{i,j}=dp_{i-1,j}

    然后没有取模,来个高精度。

    结果发现爆空间,来个滚动数组就做完了。

    #include<bits/stdc++.h>
    using namespace std;
    struct node{
    	int a[310];
    	int len;
    	node(int x=0){
    		memset(a,0,sizeof a);
    		for(len=1;x;len++) a[len]=x%10,x/=10;
    		len--;
    	}
    	int &operator [] (int i){return a[i];}
    	void fl(int l){
    		len=l;
    		for(int i=1;i<=len;i++) a[i+1]+=a[i]/10,a[i]%=10;
    		for( ;!a[len]; ) len--;
    	}
    };
    inline void print(node x){
    	for(int i=max(1,x.len);i>=1;i--)
    		cout<<x[i];
    	cout<<"\n";
    }
    inline node operator + (node x,node y){
    	node c;
    	c.len=max(x.len,y.len);
    	for(int i=1;i<=c.len;i++)
    		c[i]=x[i]+y[i];
    	c.fl(c.len+2);
    	return c;
    }
    node dp[2][2010];
    int n,m;
    string s,t;
    char npy[130];
    int main() {
    	cin>>n>>m>>s>>t,s=" "+s,t=" "+t;
    	dp[0][0]=1; 
    	npy['A']='T',npy['T']='A',npy['C']='G',npy['G']='C';
    	for(int i=1;i<=n;i++)
    		for(int j=0;j<=m;j++){
    			dp[i&1][j]=dp[(i&1)^1][j];
    			if(npy[s[i]]==t[j]) dp[i&1][j]=dp[i&1][j]+dp[(i&1)^1][j-1];
    		}
    	print(dp[n&1][m]); 
    	return 0;
    }
    
    • 1

    信息

    ID
    4429
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者