【DP】【矩阵乘法】网格游走

链接

Luogu

题目描述

有一个3*3的网格,现在每个网格上有一个机器人,每个机器人在一个单位时间后会向四方任意一个方向进行移动,问t秒后不同的方案数

思路

DP转移,矩阵快速幂加速一个点到别的点的情况求解

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define ll long long

using namespace std;

const int dx[4] = {
    
    -1, 0, 0, 1}, dy[4] = {
    
    0, -1, 1, 0};
const ll mo = 1e9 + 7;
struct matrix
{
    
    
	int n, m;
	ll a[15][15];
} A, B, ans;
int p[15][15], w[15];
ll n, sum, Ans, t, f[15][15];
bool use[15];

matrix operator * (matrix a, matrix b)
{
    
    
	matrix c;
	c.n = a.n, c.m = b.m;
	for (int i = 1; i <= c.n; i++)
	  for (int j = 1; j <= c.m; j++) c.a[i][j] = 0;
	for (int i = 1; i <= c.n; i++)
	  for (int j = 1; j <= c.m; j++)
	    for (int k = 1; k <= a.m; k++)
	      c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j] % mo) % mo;
	return c;
}

void ksm(ll t)
{
    
    
	if(t == 1) {
    
    
		B = A;
		return;
	}
	ksm(t >> 1);
	B = B * B;
	if(t & 1) B = B * A;
}

ll work(int x, int y)
{
    
    
	ans.n = 1; ans.m = 9;
	for(int i = 1; i <= 9; ++i) ans.a[1][i] = 0;
	ans.a[1][x] = 1;
	ans = ans * B;
	return ans.a[1][y];
}

void dfs(int x)
{
    
    
	if(x > 9) {
    
    
		sum = 1;
		for(int i = 1; i <= 9; ++i)
			sum = sum * f[i][w[i]] % mo;
		Ans = (Ans + sum) % mo;
		return;
	}
	for(int i = 1; i <= 9; ++i)
	{
    
    
		if(!use[i])
		{
    
    
			use[i] = 1;
			w[x] = i;
			dfs(x + 1);
			use[i] = 0;
			w[x] = 0;
		}
	}
}

int main()
{
    
    
	scanf("%lld", &t);
	for(int i = 1; i <= 3; ++i)
	for(int j = 1; j <= 3; ++j)
	{
    
    
		int num = (i - 1) * 3 + j;
		for(int k = 0; k < 4; ++k)
		{
    
    
			int tx = i + dx[k];
			int ty = j + dy[k];
			if(tx < 1 || tx > 3 || ty < 1 || ty > 3) continue;
			p[num][(tx - 1) * 3 + ty] = 1;
		}
		p[num][num] = 1;
	}
	A.n = A.m = 9;
	for(int i = 1; i <= 9; ++i)
		for(int j = 1; j <= 9; ++j)
			A.a[i][j] = p[i][j];
	ksm(t);
	for(int i = 1; i <= 9; ++i)
	for(int j = 1; j <= 9; ++j)
		f[i][j] = work(i, j);
	dfs(1);
	printf("%lld", Ans);
}

猜你喜欢

转载自blog.csdn.net/LTH060226/article/details/121170901
今日推荐