Codeforces Round #594 (Div. 2) C. Ivan the Fool and the Probability Theory

Posted xunzf0402

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #594 (Div. 2) C. Ivan the Fool and the Probability Theory相关的知识,希望对你有一定的参考价值。

题目原址:C. Ivan the Fool and the Probability Theory

题意:n×m的网格中填黑白格,最多有两个相邻,共用一条边为相邻,有几种填法。

思路:这题比赛写自闭了,一直觉得自己的思路没错,然后就残酷打脸,超级难受的那种。

从不能有3个及以上相邻可以得出,只要有两个相邻的就能确定全部的分布,那就变成了求一行的方法数量,再减去黑白相间的两种,而剩下就是黑白相间两种情况时有多少种了。

一行的求法:dp[ i ] [ 0 ]表示在第 i 个格子里放白色的放法有多少,dp[ i ] [ 1 ] 表示在第 i 个格子里放黑色的放法有多少,显然dp [ 1 ] [ 0 ] = 1;dp [ 1 ] [ 1 ] = 1 ; dp [ 2 ] [ 0 ] = 2 ; dp [ 2 ] [ 1 ] = 2 ; 而接着就可以得到dp[ i ] [ 0 ] = dp [ i - 1 ] [ 1 ] + dp [ i - 2 ] [ 1 ] ; 第 i 个放白色那它前一个可以是放黑色,也可以前前个是放黑色,但不能前前前个,因为最多两个。后面的就是一样的。而黑色的推导是一样的,就能得到dp [ i ] = dp[ i - 1 ] + dp [ i - 2 ]。dp[ i ]表示有i个格子有几种放法。

接下来就会发现,列只有两种情况(先放黑块或先放白块,接着交替出现),可以把其中每一行都看成而第一个是相同颜色。就成了在一列n个格子里放黑白块,最多两个一样颜色相邻。

最后结果就是 dp [ n ] + dp [ m ] - 2 了。

AC代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 ll x,y;
 8 ll dp[100010];
 9 const ll MOD=1e9+7;
10 void ress(){
11     dp[1]=2;
12     dp[2]=4;
13     for(ll i=3;i<100010;i++)
14         dp[i]=(dp[i-1]+dp[i-2])%MOD;
15 }
16 void sol(){
17     ress();
18     ll ans=(dp[x] + dp[y]-2)%MOD;
19     cout<<ans;
20 }
21 int main(){
22     cin>>x>>y;
23     sol();
24     return 0;
25 }

 

以上是关于Codeforces Round #594 (Div. 2) C. Ivan the Fool and the Probability Theory的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #594 (Div. 2) C. Ivan the Fool and the Probability Theory

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

CF Round 594

codeforces 594

Codeforces 594D REQ 线段树