Description 定义波浪序列:a1 > a2 < a3…,现在给出一个长度为n的序列a和一个长度为m的序列b,求a和b的公共波浪子序列个数 Input 第一行一整数T表示用例组数,每组用例首先输入两个整数n和b表示两个序列的长度,然后输入一个长度为n的序列a[1]~a[n]和一个长度为m的序列b[1]~b[m] (1<=T<=15,1<=n,m,a[i],b[j]<=2000) Output 输出a和b的公共波浪子序列个数 Sample Input 1 3 5 1 5 3 4 1 1 5 3 Sample Output 10 Solution Code
#include<cstdio> #include<cstring> using namespace std; const int maxn=2001,mod=998244353; namespace fastIO { #define BUF_SIZE 100000 //fread -> read bool IOerror=0; inline char nc() { static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE; if(p1==pend) { p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin); if(pend==p1) { IOerror=1; return -1; } } return *p1++; } inline bool blank(char ch) { return ch==' '||ch=='\n'||ch=='\r'||ch=='\t'; } inline void read(int &x) { char ch; while(blank(ch=nc())); if(IOerror)return; for(x=ch-'0';(ch=nc())>='0'&&ch<='9';x=x*10+ch-'0'); } #undef BUF_SIZE }; using namespace fastIO; int T,n,m,a[maxn],b[maxn],dp[maxn][2],sum[maxn][2]; int inc(int x,int y) { return x+y>=mod?x+y-mod:x+y; } int main() { read(T); while(T--) { read(n),read(m); for(int i=1;i<=n;i++)read(a[i]); for(int i=1;i<=m;i++)read(b[i]); memset(sum,0,sizeof(sum)); int ans=0; for(int i=1;i<=n;i++) { int num0=0,num1=1; for(int j=1;j<=m;j++) { dp[j][0]=dp[j][1]=0; if(a[i]==b[j]) { dp[j][0]=num1,dp[j][1]=num0; ans=inc(ans,inc(num0,num1)); } else if(a[i]<b[j])num1=inc(num1,sum[j][1]); else num0=inc(num0,sum[j][0]); } for(int j=1;j<=m;j++) sum[j][0]=inc(sum[j][0],dp[j][0]),sum[j][1]=inc(sum[j][1],dp[j][1]); } printf("%d\n",ans); } return 0; }