[hdu6377][百度之星2018]度度熊看球赛

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

猜你喜欢

转载自blog.csdn.net/zzrh2018/article/details/81738972