Codeforces Round #594 (Div. 2) C. Ivan the Fool and the Probability Theory (思维)acm
题意:给你一个n*m的方格,你可以在格子中放入1或0.任意一个格子与它所有相邻(有公共边)的格子最多只有一个相同。问有多少种方法。
思路:我们先考虑只有一维的情况,发现是一个斐波那契数列。处理出来记为a[];
当第一行确定时,1:如果第一行有至少一个(相邻的2个格)相同,那么整个矩阵就可以通过这2个相邻切相同的格来推演出来。
比如 2*6的矩阵
101001
010110
假设第一行是101001,那么因为第一行的第4,5个都为0,
所以第二行的第4,5个只能都是1.
接下来确定了第一行,第二行的第4和5个,那么第二行其它的也都确定了,
同理如果有第3行也可以确定。
2:除了第一种情况,剩下的都是第一行没有任意2个相邻的格子相同。
此时我们不妨吧(10101010.。。。)看为1号串,(01010101.。。。)看为2号串,
当第一行为1号串,第二行只能是2号串,第3行为1号串。。。。
(或者反过来,第一行为2,第二行为1。。。。)
那么这种情况恰好又符合该题只有一维的情况。
综上 ans=a[n]-2+a[m].a[n]-2是第一种情况,a[m]是第二种情况。
ps:该题好像有dp的做法,不过本弱并不会。。。qaq
#include<bits/stdc++.h> using namespace std; #define ll long long const ll mod = 1e9+7; const int maxn = 1e5+5; ll f[maxn]={2,2}; int main() { int n,m; for(int i=2;i<=100000;i++) f[i] = (f[i-1] + f[i-2]) % mod; scanf("%d%d",&n,&m); printf("%lld\n",(f[n]-2+f[m]+mod)%mod); return 0; }