bnuoj Andrew and the Strings(dp)

来源:互联网 发布:淘宝店多个店铺管理 编辑:程序博客网 时间:2024/06/06 04:18
B. Andrew and the Strings
Time Limit: 1000msMemory Limit: Unknown KB 64-bit integer IO format: %lld Java class name: Main
Submit Status PID: 40493
Andrew likes strings very much.

He has two strings A and B of N lower alphabet letters. We denote S[i, j] as the substring from ith to jth characters of string S.

Andrew is interested in the number of such fours of integers (LA, RA, LB, RB), where 1 ≤ LA ≤ RA ≤ N, 1 ≤ LB ≤ RB ≤ N, and RA − LA = RB − LB, such that the Hamming distance between substrings A[LA, RA] and B[LB, RB] is not greater than K. Here the Hamming distance between two strings of the same length is the number of unequal characters on the same positions of strings.

Help him and find this number.

Input
The first line of the input contains an integer T, denoting the number of test cases. The description of T test cases follows. The first line of each test case contains two space-separated integers N and K. The second line contains string A, and the third line contains string B.

Output
For each test case, output an integer, denoting the number of fours (LA, RA, LB, RB) satisfying the conditions described in the problem statements.

Constraints
1 ≤ T ≤ 10
1 ≤ N ≤ 1000
1 ≤ K ≤ N
Both A and B are contain only N lower alphabet letters
Example
Input:
3
3 2
aba
abb
3 2
abc
def
1 1
a
a

Output:
14
13
1
Explanation
Example case 1: There are 14 fours as following:
(1, 1, 1, 1) : dist(A[1, 1], B[1, 1]) = dist(a, a) = 0 ≤ 2
(1, 1, 2, 2) : dist(A[1, 1], B[2, 2]) = dist(a, b) = 1 ≤ 2
(1, 1, 3, 3) : dist(A[1, 1], B[3, 3]) = dist(a, b) = 1 ≤ 2
(2, 2, 1, 1) : dist(A[2, 2], B[1, 1]) = dist(b, a) = 1 ≤ 2
(2, 2, 2, 2) : dist(A[2, 2], B[2, 2]) = dist(b, b) = 0 ≤ 2
(2, 2, 3, 3) : dist(A[2, 2], B[3, 3]) = dist(b, b) = 0 ≤ 2
(3, 3, 1, 1) : dist(A[3, 3], B[1, 1]) = dist(a, a) = 0 ≤ 2
(3, 3, 2, 2) : dist(A[3, 3], B[2, 2]) = dist(a, b) = 1 ≤ 2
(3, 3, 3, 3) : dist(A[3, 3], B[3, 3]) = dist(a, b) = 1 ≤ 2
(1, 2, 1, 2) : dist(A[1, 2], B[1, 2]) = dist(ab, ab) = 0 ≤ 2
(1, 2, 2, 3) : dist(A[1, 2], B[2, 3]) = dist(ab, bb) = 1 ≤ 2
(2, 3, 1, 2) : dist(A[2, 3], B[1, 2]) = dist(ba, ab) = 2 ≤ 2
(2, 3, 2, 3) : dist(A[2, 3], B[2, 3]) = dist(ba, bb) = 1 ≤ 2
(1, 3, 1, 3) : dist(A[1, 3], B[1, 3]) = dist(aba, abb) = 1 ≤ 2

Example case 2: The four (1, 3, 1, 3) no longer satisfies the conditions, because

(1, 3, 1, 3) : dist(A[1, 3], B[1, 3]) = dist(abc, def) = 3 > 2


题目大意:

告诉你两串字符串,要求找出两个字符串里有多少对子串是符合要求的。要求是:两串子串的长度相等,并且对应位置不同的字符的个数小于等于k。

解题思路:

叉姐的训练赛,我果然还是太弱了。听了ink 的解题思路后,才知道这道题目是一个动态规划的题目。开始一直把它当做是字符串来做,我也真是醉了。

我们的动态规划转移方程是这样的:dp[i][j] 表示A串从第i个字符开始,B串从第j个字符开始匹配最长能够匹配到的长度。他可以从i-1,j-1的状态转移过来。如果A[i-1]跟B[j-1]一样,那么dp[i][j] =  dp[i-1][j-1]-1 否则就是再往后找,直到他们的长度达到最大。 只要i,j为第一个字符的时候初始化的时候特判一下就好了。

真是一个神奇的动态规划。让自己再一次见到了智商的差距。

代码如下:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int dp[1111][1111];char s1[1111],s2[1111];int main(){    int T,n,m,i,j,x,y,num,ans;    scanf("%d",&T);    while(T--)    {        scanf("%d%d%s%s",&n,&m,s1+1,s2+1);        memset(dp,0,sizeof(dp));        for(i=1; i<=n; i++)        {            for(j=1; j<=n; j++)            {                //if(dp[i-1][j-1]==0)                if(i==1||j==1)                {                    num=0;                    x=i;                    y=j;                    for(; x<=n&&y<=n; x++,y++)                    {                        if(s1[x]!=s2[y])num++;                        if(num>m)break;                    }                    dp[i][j]=min(x-i,y-j);                }                else                {                    if(s1[i-1]==s2[j-1])dp[i][j]=min(dp[i-1][j-1]-1,min(n-i+1,n-j+1));                    else                    {                        x=dp[i-1][j-1]+i-1;                        y=dp[i-1][j-1]+j-1;                        num=0;                        for(; x<=n&&y<=n; x++,y++)                        {                            if(s1[x]!=s2[y])num++;                            if(num>1)break;                        }                        dp[i][j]=min(x-i,y-j);                    }                }            }        }        ans=0;        for(i=1; i<=n; i++)        {            for(j=1; j<=n; j++)            {                // printf("%d %d %d !\n",i,j,dp[i][j]);                ans+=dp[i][j];            }        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击