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);
}
}