hdu 5791 Two 二维前缀和

本文介绍了一种通过动态规划算法解决子序列匹配问题的方法。该算法用于计算两个序列拥有的相同子序列对的数量,并考虑了子序列不连续的情况。文章提供了详细的实现思路及代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Alice gets two sequences A and B. A easy problem comes. How many pair of sequence A' and sequence B' are same. For example, {1,2} and {1,2} are same. {1,2,4} and {1,4,2} are not same. A' is a subsequence of A. B' is a subsequence of B. The subsequnce can be not continuous. For example, {1,1,2} has 7 subsequences {1},{1},{2},{1,1},{1,2},{1,2},{1,1,2}. The answer can be very large. Output the answer mod 1000000007.

Input

The input contains multiple test cases. 

For each test case, the first line cantains two integers N,M(1N,M1000). The next line contains N integers. The next line followed M integers. All integers are between 1 and 1000.

Output

For each test case, output the answer mod 1000000007.


才发现这道题是多校的。。。感觉还是比较水的。

公式比较好推,我用dp[i][j]表示以a的第i位和b的第j位结尾的符合题意的子串的个数,sum【i】【j】则是dp的一个二维前缀和。二维前缀和怎么求呢?可以百度二维前缀和23333.

然后假如a【i】==b【j】那么dp【i】【j】=sum【i-1】【j-1】,否则为0,算出dp后更新sum的值。

另外还有一个坑点,WA了几发,就是出现负数要还原,这点在有mod的题目里很重要。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<limits.h>
#include<float.h>
#include<algorithm>
using namespace std;
const int MOD=1000000007;
int dp[1010][1010],sum[1010][1010],a[1010],b[1010],n,m;
int main(void)
{
    while(cin>>n>>m)
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=m;i++)
            scanf("%d",&b[i]);
        memset(dp,0,sizeof(dp));
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                sum[i][j]=(sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1])%MOD;
                sum[i][j]=(sum[i][j]+MOD)%MOD;
                if(a[i]==b[j])
                    dp[i][j]=(sum[i-1][j-1]+1)%MOD;
                else
                    dp[i][j]=0;
                sum[i][j]=(sum[i][j]+dp[i][j])%MOD;
            }
        }
        cout<<sum[n][m]<<endl;

    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值