dp找对对象
第一思路考虑按位置dp然后炸了
可以按每队情侣是否在一起dp
f[i][j]代表到第i对情侣j对在一起的方案数
#include <assert.h> //设定插入点
#include <ctype.h> //字符处理
#include <errno.h> //定义错误码
#include <float.h> //浮点数处理
#include <limits.h> //定义各种数据类型最值常量
#include <locale.h> //定义本地化函数
#include <math.h> //定义数学函数
#include <stdio.h> //定义输入/输出函数
#include <stdlib.h> //定义杂项函数及内存分配函数#include <string.h> //字符串处理
#include <time.h> //定义关于时间的函数#include <wchar.h> //宽字符处理及输入/输出
#include <wctype.h> //宽字符分
using namespace std;
const long long mod=998244353;
long long a,b,f[1001][1001],ans;
long long pm(long long a,long long b)
{ long long t=1;
if (b==0) return 1;
for (;b;a=(a*a)%mod,b=b/2) if (b%2) t=(t*a)%mod;
return t;
}
void deal()
{ f[0][0]=1;
f[1][0]=0;
f[1][1]=2;
for (int i=2;i<=1000;i++)
for (int j=0;j<=i;j++)
{ if (j>0) f[i][j]=(f[i][j]+f[i-1][j-1]*(2*i-j)*2)%mod;
if (j+1<=i-1) f[i][j]=(f[i][j]+f[i-1][j+1]*(j+1)*(2*i-j-2)*2)%mod ;
if (j+2<=i-1) f[i][j]=(f[i][j]+f[i-1][j+2]*(j+2)*(j+1))%mod;
if (j<=i-1) f[i][j]=(f[i][j]+f[i-1][j]*(2*i-j-2)*(2*i-j-1)+f[i-1][j]*j*2)%mod;
}
}
int main()
{
deal();
//cout<<f[1][1]<<endl;
//cout<<f[2][1]<<endl;
// printf("%d\n",f[1000][1000]);
while (scanf("%d%d",&a,&b)!=EOF)
{ ans=0;
for (int i=0;i<=a;i++)
{ ans=(ans+pm(b,i)*f[a][i])%mod;
}
printf("%d\n",ans%mod);
}
}