• 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 }
  • 相关阅读:
    UIWebView显示乱码问题
    Masonry控制台打印约束冲突问题解决
    iOS正则表达式之验证问题总结
    Cannot assign to 'self' outside of a method in the init family
    iOS模拟器设置输入中文
    python递归中的return"陷阱"
    自己动手写一个U盘拷贝小工具
    selenium对富文本框的处理
    selenium webdriver如何添加cookie
    利用ChromeOptions()加载用户配置
  • 原文地址:https://www.cnblogs.com/xunzf0402/p/11715785.html
Copyright © 2020-2023  润新知