多校赛第五场

今天在体检,没能和队友一起了,之后的多校赛都要单刷了,天朝奇怪的征兵政策,我测完视力,一群人盯着我看。。。老子是写轮眼不行吗,右眼用多了万花筒,视力下降了。吐槽就到这里了

hdu 5791

Problem Description

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(1≤N,M≤1000). 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,不过还是搞错不少地方。。。
实际上思路很简单,dp[i][j]表示A序列前i个数和B序列前j个数的相同子序列对有多少个,那么当a[i] != b[j]时,dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1],而当a[i] = b[j]时,dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + 1。举个简单的例子来说明一下。A:1 2 3 4 B:1 2 4,这种情况下dp[3][3]应该包括(1),(2),(1,2),dp[4][2]应该包括(1),(2),(1,2),而dp[4][3]应该包括(1),(2),(1,2),(1,4),(2,4),(1,2,4),(4)。

代码

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

const int kMaxn = 1000 + 10;
const int kMod = 1000000007;

int dp[kMaxn][kMaxn];
int a[kMaxn],b[kMaxn];

int main() {
    int n,m;
    while(~scanf("%d %d", &n, &m)) {
        memset(dp, 0, sizeof(dp));
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        for(int i = 1; i <= m; i++)
            scanf("%d", &b[i]);
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(a[i] == b[j])
                    dp[i][j] = (dp[i - 1][j] + dp[i][j - 1] + 1) % kMod;
                else {
                    dp[i][j] = (dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1]) % kMod;
                    if(dp[i][j] < 0) 
                        dp[i][j] += kMod;
                }
            }
        }
        printf("%d\n", dp[n][m]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值