bzoj4417 [Shoi2013]超级跳马 矩乘

在手玩的时候找转移的规律,发现可以奇偶分类,不同奇偶的点相邻3行全都可以+1转移,同奇偶的点不可以转移

所以对于每一行,都记录奇偶两种的前缀和,就可以省去扫同行的点

注意,由于是两两转移,要注意区分12->34 中的1->4和 1->2,为了避免3->4就需要独立的12->3   12->4

可以以3为桥梁 12->3->4,注意写清楚不要乱

注意特判n=1


码:

#include<iostream>
#include<cstdio>
using namespace std;
#define HA 30011
int n,m,i,j,k,f[150][150],b[150],c[150][150],a[150],g[150][150];
int main()
{
	scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
	f[i][i]=1;	
}
for(i=1+n;i<=2*n;i++)
{
	if(i-n-1>=1)f[i][i-n-1]=1;
	if(i-n+1<=n)f[i][i-n+1]=1;
	f[i][i-n]=1;
}//下一个左边的转移 
for(i=1+n;i<=n*2;i++)
{
f[i][i]=1;	
}
for(i=1;i<=2*n;i++)
for(j=1;j<=n;j++)
{
if(j>1)f[i][j+n-1]+=f[i][j];
if(j<n)f[i][j+n+1]+=f[i][j];
	f[i][j+n]+=f[i][j];
}
//下一个右边的转移 
	a[1]=1;
	a[1+n]=a[2+n]=1;
	int lin=m/2;
lin--;
	while(lin)
	{
		if(lin&1)//答案转移上 
		{
			for(i=1;i<=n*2;i++)
			for(j=1;j<=n*2;j++)//n*2 to n*2
			{
				b[j]+=a[i]*f[i][j];	
				b[j]%=HA;		
			}			
		for(i=1;i<=2*n;i++)a[i]=b[i],b[i]=0;
		}
		lin/=2;
		for(i=1;i<=n*2;i++)
		for(j=1;j<=n*2;j++)	
		for(k=1;k<=n*2;k++)
		{
			c[i][k]+=f[i][j]*f[j][k];
			c[i][k]%=HA;		
		}		
		for(i=1;i<=2*n;i++)
		for(j=1;j<=2*n;j++)
		f[i][j]=c[i][j],c[i][j]=0;
	}
	if(m&1)
	printf("%d",(a[2*n]+(n==1?0:a[2*n-1]))%HA);
	else printf("%d",(a[n]+(n==1?0:a[n-1]))%HA);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值