BZOJ 4417: [Shoi2013]超级跳马【矩阵快速幂优化dp

矩阵快速幂优化dp……大概似乎还是很裸的……然而我昨天才学会这套理论于是考试只好在200+分场里110滚粗【哭

嗯考虑用f[i][j]表示在第i行第j列的方案总数

转移的话,因为只能跳奇数格,所以f[i][j]=f[i-2][j]+f[i-1][j-1]+f[i-1][j]+f[i-1][j+1](边界啥的判一下就是了

如果不考虑从i-1列转移的方案,那么f[i][j]==f[i-2][j],于是再加上相邻的那三个格子的贡献就好了……

发现第二维足够小,而且只和前两列的结果有关,所以直接用矩阵搞一搞就好


用一个2n*1的矩阵来记录答案,上面n行记录f[i-1],下面n行记录f[i-2],转移的时候把上面一半粘到下面来,f[i]就按照递推式更新就好

当n==3时,转移矩阵差不多是这样的↓(这四块的位置应该随便吧……反正差不多就好23333

1 1 0 1 0 0

1 1 1 0 1 0

0 1 1 0 0 1

1 0 0 0 0 0

0 1 0 0 0 0

0 0 1 0 0 0

#include
#define MAXN 105
#define MAXM 1000000057
#define MOD 30011
using namespace std;	int n,m;

struct matrix{
	int d[MAXN][MAXN];
	int x,y;
	matrix(){x=y=0,memset(d,0,sizeof d);}
	matrix(int xx):x(xx),y(xx){
		memset(d,0,sizeof d);
		for(int i=0;i>=1,TMP=TMP*TMP)
			if(cf&1)
				RTN=RTN*TMP;
		return RTN;
	}
	void write(){
		for(int i=0;im)	return puts("0"),0;
	----m;
	
	A=B=matrix(n<<1,n<<1);
	P=matrix(n<<1,1);
	P.d[0][0]=P.d[1][0]=1;
	if(n==1&&m>=2)	P.d[1][0]=0;
//	P.write();
	for(int i=0;i


你可能感兴趣的:(OI,BZOJ,矩阵快速幂,dp)