C. Ivan the Fool and the Probability Theory 题意: 给n行m列,让构造黑白块,要求每个块周围最多一个和自己颜色相同的块,问最多有多少种构造方法? 思考 : 首先如果第一行是 这样的话,那么下面的每一行一定都确定了因为有两个相同的颜色出现, 但是如果是这样 黑白相间的情况的话, 那么第一行确定的话,第二行就会有两种情况,第一种是和第一行一样,第二种是和第一行完全相反。 黑白相间的情况有两种,黑白黑白黑 和白黑白黑白 这两种 当两种情况任意一种出现的时候,他的种类数就可以变成竖着来求一次dp的情况。 所以总的种类数 = 第一行所有的种类数 - 黑白相间的两种情况 + 当黑白相间的时候的竖着的情况 dp[i][0] 代表第i个位置放白色的情况 dp[i][1]代表第i个位置放黑色的情况 dp[i][1] = dp[i-1][0]+ dp[i-2][0]; dp[i][0] = dp[i-1][1]+ dp[i-2][1]; 最后求出所有的种类数加减就可以了 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e6+6; const int mod = 1e9+7; ll n, m; ll dp[maxn][2]; int main() { cin >> n >> m; if(n > m) swap(n, m); // 1 black 0 white dp[1][1] = 1, dp[1][0] = 1; dp[2][1] = 2, dp[2][0] = 2; for(int i = 3; i <= m; i ++) { dp[i][1] = dp[i-1][0]%mod + dp[i-2][0]%mod; dp[i][1] %= mod; dp[i][0] = dp[i-1][1]%mod + dp[i-2][1]%mod; dp[i][0] %= mod; } cout << ((dp[m][0]+dp[m][1])%mod + (dp[n][0] + dp[n][1])%mod - 2)%mod << endl; return 0; }