zoukankan      html  css  js  c++  java
  • 牛客多校第五场D Double Strings

    题意: 给定两个字符串A,B求长度相同的AB子串,使得子串的前面部分相等,且第一个不相等的位置B>A。求这样的子串个数

    场上把两个DP写反了,应该先求前面部分相等的种数,再对于后半部分的大于DP

    思路:f[i][j]表示A的前i个字符与B的前j个字符能组成多少相等的子串。

    若AB不相等,f[i][j]=f[i--1][j]+f[i][j-1]-f[i-1][j-1];

    若AB相等,f[i][j]额外加上f[i-1][j-1],表示一定带有当前这两个字符的相等子串

    求完f之后再利用f求解

    dp[i][j]表示A前i个字符与B前j个字符的解数。

    dp[i][j]=dp[i-1][j]+dp[i][j-1]   (原来一直觉得这里要减掉一个dp[i-1][j-1]后来问了别人才知道因为这里如果前面i-1,j-1的子串是符合条件的,那么这里i与j无论放什么都没有关系,所以还要加回去,就正好抵消了)

    如果b[j]>a[i] dp[i][j]额外加上f[i-1][j-1]

    下附代码:

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 char a[5005],b[5005];
     5 int dp[5005][5005],f[5005][5005];
     6 ll res=0;
     7 const int mod=1e9+7;
     8 int main(){
     9     scanf("%s%s",a+1,b+1);
    10     int n=strlen(a+1),m=strlen(b+1);
    11     memset(f,0,sizeof(f));
    12     f[0][0]=1;
    13     for (int i=1; i<=m; i++) f[0][i]=1;
    14     for (int i=1; i<=n; i++) f[i][0]=1;
    15     for (int i=1; i<=n; i++){
    16         for (int j=1; j<=m; j++){
    17             f[i][j]=((f[i-1][j]+f[i][j-1])%mod-f[i-1][j-1]+mod)%mod;
    18             if (a[i]==b[j]){
    19                 f[i][j]=(f[i-1][j-1]+f[i][j])%mod;
    20             }  
    21         }
    22     }
    23     for (int i=1; i<=n; i++){
    24         for (int j=1; j<=m; j++){
    25             dp[i][j]=(dp[i-1][j]+dp[i][j-1])%mod;
    26             if (a[i]<b[j]) dp[i][j]=(dp[i][j]+f[i-1][j-1])%mod;
    27         }
    28     }
    29     printf("%lld",dp[n][m]);
    30 }
    View Code
  • 相关阅读:
    java版扫雷
    隔离级别
    Servlet Analysis
    Session&Cookie
    centos上部署应用到tomcat
    在CentOS 7中安装与配置Tomcat-8.5方法
    centos7中安装、配置jdk(转载)
    java RE Validation常用
    hello2 source Analysis
    serlvet中的过滤器filter
  • 原文地址:https://www.cnblogs.com/i-caigou-TT/p/15086545.html
Copyright © 2011-2022 走看看