2017第四次多校联合hdu6078

来源:互联网 发布:淘宝头条怎么申请 编辑:程序博客网 时间:2024/06/14 17:51

题目

题意:给你a,b两个序列,想要找出两个序列f,g(均为递增序列),使afi=bgi,且af1,af2......afn是波浪型},计算·有多少种f,g序列。

题解:固定ai,去找bi,只需要考虑相等的情况,不相等的情况只需要相加就好了。
波浪一定会有波峰和波谷,如果对于一个ai来说,如果在b中只有一个数字与他相等,那只有以ai为波谷或者在之前出现以ai为波峰的情况。所以整体思路就是寻找每一个ai=bi的情况,顺便考虑与前面能形成波浪的情况。
(代码还是比较好懂的)

#include<bits/stdc++.h>using namespace std;#define ll long longconst int maxn=20005;const int mod=998244353;ll dp[maxn][2],sum[maxn][2];int n,m;int a[maxn],b[maxn];int main(){    int t;    scanf("%d",&t);    while(t--)    {        memset(dp,0,sizeof dp);        memset(sum,0,sizeof sum);        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]);        ll ans=0;        for(int i=1;i<=n;i++)        {            int p=1,v=0;            for(int j=1;j<=m;j++)            {                if(a[i]==b[j])                {                    dp[j][0]=p;                    dp[j][1]=v;                    ans=(ans+p+v)%mod;                }                else if(a[i]>b[j])                {                    v=(v+sum[j][0])%mod;                }                else if(a[i]<b[j])                {                    p=(p+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);    }}
原创粉丝点击