Codeforces Round #594 (Div. 1) A. Ivan the Fool and the Probability Theory ###K ###K //K

题目链接:https://codeforces.ml/contest/1239/problem/A

题意:给定n*m的矩阵,每个格子可以涂黑色或者白色,要求每个格子的颜色至多只能和相邻的一个格子相同颜色 共享边为相邻的格子,为有多少种涂色方法

思路:模拟写一下就能发现,相邻两行之间要么相同要么相反, 而如果要相同的话只能是黑白相间的时候相同,

那么考虑 ans= 第一行黑白相间的情况+其他的情况   ,  其他的情况就是dp[m][1]+dp[m][0]除去黑白相间的两种情况就-2

再考虑确定第一行为黑白相间的时候,怎么求, 如果确定第一行为黑白相间,那么第一列确定之后,所有的情况也确定了

所以 情况就是dp[n][1]+dp[n][0]

 

考虑如何用dp来求 第一行的方案数, 用dp[i][0]表示第i个格子涂白色,dp[i][1]表示第i个格子涂黑色 

那么考虑如何转移,  如果当前的格子是黑格子 那么上一个可以是黑格子,也可以是白格子,上一个是白格子的话 显然+dp[i-1][0]即可

上一个是黑格子的话 用黑格子来转移是不行的,因为dp[i-1][1]中包含了第i-2个是黑格子  所以考虑用白格子来转移,假设上一个是黑格子的话,那么i-2个就一定是白格子

所以dp[i][1]=dp[i-1][0]+dp[i-2][0]  同理dp[i][0]=dp[i-1][1]+dp[i-2][1]

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define pb push_back
 6 const int maxn=1e5+10;
 7 const int mod=1e9+7;
 8 
 9 ll dp[maxn][2];
10 
11 
12 
13 int main()
14 {
15     ios::sync_with_stdio(false);
16     cin.tie(0);
17     dp[1][1]=dp[1][0]=1;
18     dp[2][1]=dp[2][0]=2;
19     for(int i=3;i<maxn;i++)
20     {
21         dp[i][0]=(dp[i-1][1]+dp[i-2][1])%mod;
22         dp[i][1]=(dp[i-1][0]+dp[i-2][0])%mod;
23     }
24 
25     int n,m;
26     cin>>n>>m;
27     ll ans=dp[n][0]+dp[m][0]-1;
28     ans*=2;
29     ans=(ans+mod)%mod;
30     cout<<ans<<'\n';
31 
32 
33 
34 
35 }
View Code

 

posted @ 2020-08-09 14:22  canwinfor  阅读(161)  评论(0)    收藏  举报