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

C. Ivan the Fool and the Probability Theory

time limit per test

1 second

memory limit per test

512 megabytes

input

standard input

output

standard output

Recently Ivan the Fool decided to become smarter and study the probability theory. He thinks that he understands the subject fairly well, and so he began to behave like he already got PhD in that area.

To prove his skills, Ivan decided to demonstrate his friends a concept of random picture. A picture is a field of n

rows and m

columns, where each cell is either black or white. Ivan calls the picture random if for every cell it has at most one adjacent cell of the same color. Two cells are considered adjacent if they share a side.

Ivan's brothers spent some time trying to explain that it's not how the randomness usually works. Trying to convince Ivan, they want to count the number of different random (according to Ivan) pictures. Two pictures are considered different if at least one cell on those two picture is colored differently. Since the number of such pictures may be quite large, print it modulo 109+7

.

Input

The only line contains two integers n

and m (1≤n,m≤100000

), the number of rows and the number of columns of the field.

Output

Print one integer, the number of random pictures modulo 109+7

.

Example

Input

Copy

2 3

Output

Copy

8

Note

The picture below shows all possible random pictures of size 2

by 3

.

题意:n*m的长方形中,一共有两种颜色,问每一个块相邻最多有一个与之相同颜色的块的染色方案数

思路:首先我们可以发现,如果有相邻两块颜色一样,那么他们下一行一定是确定的,因为这两块的下面两个块颜色不能与之相同,直角是不能出现的。然后就可以发现,无论旁边是啥颜色,都会变成与之想反,简单地说就是,第一行如果存在相邻两块颜色一样,那么这个图形整个的图案就确定了。

但是有一种特殊情况,那就是交错出现黑和白,这种情况下,下面有时候是可以与上面相同的,也就是这种情况下图案不唯一。但是这也不是个问题,因为列上满足要求的方法跟行一样,只要你能保证每一列中都不要出现相邻超过三个相同颜色就行,因为横着都是交错出现,不用担心。所以问题就转换成了,如果只有一行的话,一共有几种方案呢?

 

dp[i][0]为第i个填白色的方案数,dp[i][1]表示第i个填黑色的方案数,

那么显而易见,

dp[1][0]=dp[1][1]=1(只有一个格子,又规定了颜色,肯定只有一种了),

dp[2][0]=dp[2][1]=2(两个格子的话,不管第二个啥颜色,第一个都能乱填,反正两个格子没法出现三个一样的情况),

然后就是

dp[i][0]=dp[i-1][1]+dp[i-2][1]

 

dp[i][1]=dp[i-1][0]+dp[i-1][0]

 

二者合体,发现dp[i][0]+dp[i][1]=dp[i-1][0]+dp[i-1][0]+dp[i-1][1]+dp[i-2][1],那就直接合体,dp[i]=dp[i-1]+dp[i-2]

所以就是,一列m个有dp[m]种情况,其中要踢掉黑白相间的两种情况,这两种情况所占的就是n行的情况数,为dp[n],所以答案就是dp[n]+dp[m]-2。

感谢:https://blog.csdn.net/weixin_42856843/article/details/102655689

           https://blog.csdn.net/toohandsomeIeaseId/article/details/102668813

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
const int maxn=1e5+10;
ll f[maxn];
int main()
{
    int n,m;
    cin>>n>>m;
    if(n<m)
    {
        swap(n,m);
    }
    f[1]=2,f[2]=4;
    for(int i=3;i<=n;i++)
    {
        f[i]=f[i-1]+f[i-2];
        f[i]%=mod;
    }
    cout<<(f[n]+f[m]-2)%mod<<endl;
    return 0;
}

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值