HDU

来源:互联网 发布:mac绘画录制软件 编辑:程序博客网 时间:2024/05/29 17:50

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6078

题目大意:找到A,B数组的公共子序列,且公共子序列能构成波浪的总方案数。

参考来源:http://blog.csdn.net/weixin_36571742/article/details/77184861

AC代码:

#include<cstdio>#include<cstring>using namespace std;const int MAXN = 2000 + 5;const int MOD = 998244353;typedef long long LL;int a[MAXN], b[MAXN], dp[MAXN][2];void toSolve(const int& n,const int& m){    for (int i = 1;i <= n;++i)    {        LL down = 0, up = 0;//记录能与A[i]匹配的B[j]之前的已经构成波浪的波峰和波谷        for (int j = 1;j <= m;++j)        {            if (a[i] == b[j])            {                dp[j][0] = (1 + dp[j][0]) % MOD;//波谷都能独立作为一个点                dp[j][0] = (down + dp[j][0]) % MOD;//波谷的总和等于前面已经能组合成波浪的波峰的方案和之前该位置已经能作为波谷的方案                dp[j][1] = (up + dp[j][1]) % MOD;            }            else if (a[i] > b[j])                up = (up + dp[j][0]) % MOD;//说明B[j]能作为待会儿与a[i]匹配的B[j]的波谷            else                down = (down + dp[j][1]) % MOD;//同理        }    }}int main(){    int t;scanf("%d", &t);    while (t--)    {        memset(dp, 0, sizeof(dp));        int n, m;        scanf("%d%d", &n, &m);        for (int i = 1;i <= n;++i)            scanf("%d", a + i);        for (int i = 1;i <= m;++i)            scanf("%d", b + i);        toSolve(n, m);        LL ans = 0;        for (int i = 1;i <= m;++i)            ans = (ans + dp[i][0] + dp[i][1]) % MOD;        printf("%I64d\n", ans);    }    return 0;}
原创粉丝点击