hud 6078 Wavel Sequence

hud 6078 Wavel Sequence
题目大意:给你两个序列a,b,让你找出两个函数 f 和 g 使得 a[f]=b[g],并且a[f1],a[f2],a[f3]……a[fk]满足 序列a1 < a2 > a3 < a4……为你满足关系的 f 和 g有多少种
解题思路:不难想到我们可以单独考虑每个数字,看它作为波峰有多少种情况,波谷有多少种情况,然后求和。但是具体怎么求每个数字作为波峰的情况和波谷的情况呢?因为我们要用a数组来构造波浪,所以我们不妨可以将a数组固定,然后根据条件在b数组中寻找a中每个数据可能作为波峰和波谷的所有情况。具体要怎么做看代码

#include <bits/stdc++.h>

using namespace std;
const int mod = 998244353;
int dp[2005][2],sum[2005][2];
/**
dp[][0]用来保存b数组中这个值作为波谷的情况
dp[][1]用来保存b数组中这个值作为波峰的情况
sum[][0]用来保存b数组中这个值作为波谷的总情况
sum[][1]用来保存b数组中这个值作为波峰的总情况
*/
int main()
{
    int T;scanf("%d",&T);
    while(T--){
        memset(dp,0,sizeof(dp));
        memset(sum,0,sizeof(sum));
        int n,m,a[2005],b[2005];
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int j = 1; j <= m;j++)
            scanf("%d",&b[j]);
        long long ans = 0,cnt0,cnt1;///ans用来存f和g共有多少种选择,从cnt1用来保存当前值做波峰的情况,cnt0用来保存做波谷的情况
        for(int i=1;i<=n;i++){
            cnt0 = 1;cnt1 = 0;///因为每个数字都可以单独作为波谷,所以波谷初始值为1.
            for(int j = 1; j <= m; j ++){
                dp[j][0] = dp[j][1] = 0;
                if(a[i] == b[j])///表示此时已经找到一组可以为波浪的数据,并将这个波峰,波谷的值记下,方便后边使用,ans要累加上
                {
                    dp[j][0] = cnt0;
                    dp[j][1] = cnt1;
                    ans = (ans + cnt0 + cnt1)%mod;
                }
                else if(a[i] > b[j])///如果当前这个值比a[i]要小的话说明a[i]可以作为波峰,这个时候它可以承接前边所有的波谷的情况,所以要加上前边波谷的所有情况
                    cnt1 = (cnt1 + sum[j][0])%mod;
                else///如果当前这个值比a[i]要大的话说明a[i]可以作为波谷,这个时候它可以承接前边所有的波峰的情况,所以要加上前边波谷的所有情况
                    cnt0 = (cnt0 + sum[j][1])%mod;
            }
            for(int j=1;j<=m;j++){///每次都要记录下每个点作为波峰和波谷的总情况
                if(a[i] == b[j])
                {
                    sum[j][0] = (sum[j][0]+dp[j][0])%mod;
                    sum[j][1] = (sum[j][1]+dp[j][1])%mod;
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值