格子刷油漆

题意

给一个$2*N$的矩阵,可以从任意一个格子刷起,但只能移动到和它相邻的格子(可以对角),求总的方案数,对$1e9+7$取模。

题解

设a[n]为起点为某一角落长度为n终点任意的情况数,b[n]为起点为某一角落长度为n终点必须同列的情况数。

  1. $b[i]=2^{i-1}$
  2. 当起点在四个角落,以左上角为例
    • 情况一,先向下移动,再向右移动某个位置,情况数相当于 做长度为i-1的终点任意的情况数*2 因为不需要在回到第一列,而且到第二列的时候可能是第一行或者第二行,即$a[i-1]*2$
    • 情况二,从起点出发最终回到第一列的第二行,那么情况数就是b[i]。
    • 先进入第二列,然后返回第一列另一个位置,然后再回第二列,即$22a[i-2]$
  3. 当起点在中间
    • 情况一,向左运动后回到第i列然后向右运动
    • 情况二,向右运动后回到第i列然后向左运动
  1. $a[1]=1,a[2]=6$

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <bits/stdc++.h>
#define forl(i, l, r) for (int i = l; i <= r; i++)
#define forr(i, r, l) for (int i = r; i >= l; i--)
#define for1(i, n) for (int i = 1; i <= n; i++)
#define for0(i, n) for (int i = 0; i < n; i++)
#define meminf(a) memset(a, inf, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define mem0(a) memset(a, 0, sizeof(a))
#define inlld(lld) scanf("%lld", &lld)
#define inlf(f) scanf("%lf", &f)
#define ind(d) scanf("%d", &d)
#define ins(s) scanf("%s", s)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef std::pair<long long, long long> pll;
typedef std::vector<long long> vll;
typedef std::pair<int, int> pii;
typedef unsigned long long ull;
typedef std::vector<int> vii;
typedef long double db;
typedef long long ll;
const db pi = acos((db)-1);
const ll inf =0x3f3f3f3f;
const ll mod = 1e9+7;
const int N = 1.1e5;
const db eps = 1e-8;
using namespace std;
int sign(db a) { return a < -eps ? -1 : a > eps; }
int db_cmp(db a, db b){ return sign(a-b); }

ll a[N],b[N];
int main() {
#ifdef PerpEternal
// freopen("/Users/perpeternal/Documents/Sketch/data/in.dat", "r", stdin);
// freopen("/Users/perpeternal/Documents/Sketch/data/out.dat", "w", stdout);
#endif
//ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n,ans=0;
b[1]=1;
forl(i,2,1e3){
b[i]=b[i-1]*2%mod;
}
a[1]=1;a[2]=6;
forl(i,3,1e3){
a[i]=(2ll*a[i-1]+b[i]+4ll*a[i-2])%mod;
}
ind(n);
if(n==1){
puts("2");
return 0;
}
ans=4ll*a[n]%mod;
forl(i,2,n-1){
ans=(ans+2ll*(b[i+1]*a[n-i]%mod+b[n-i+2]*a[i-1]%mod))%mod;
}
printf("%d\n",ans);
return 0;
}

引用

https://blog.csdn.net/qq_35078631/article/details/54730870