Codeforces 1248C Ivan the Fool and the Probability Theory

C. Ivan the Fool and the Probability Theory

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 nn rows and mm 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+7109+7.

Input
The only line contains two integers nn and mm (1≤n,m≤1000001≤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+7109+7.

input
2 3
output
8
Note
The picture below shows all possible random pictures of size 2 by 3.
在这里插入图片描述
思路
这种题目做了不少了,结果比赛的时候还是没有想到,需要反省一下。
题意是求nm个黑白方块的摆放方案,要求于每次相连最多只有两个同种颜色的方块相接。
这里先考虑一维的情形,可以用 f [i] 表示 1
i 个方块有多少摆放的方案,
f[1]=2,f[2]=4。
再往后,考虑f[3]的时候,可以由下面两种情况推出:
(1)f[1]后面接上两个与其结尾颜色不同的相同颜色方块 。
(2)f[2]后面接上一个与其结尾颜色不同的颜色方块。
可以得到一维的递推式为 f[n] = f[n-1] + f[n-2];
一维的摆放方案中其实可以分为两种情况:
1.单独颜色不同的方块相间 ( 黑 白 黑 )
2.颜色不同的方块相间中有颜色相同的方块相连接 ( 黑 白 白 黑 )
以这两种情况进行讨论扩展到二维:
1.当黑白相间时,由于每次相连最多只能两个同种颜色的相连,那么可以把每一 行黑白相间压缩成一个方块,压缩后的方块颜色取与当前队头第一个元素相同(因为黑白相间,第一个方块的元素决定后,后面的方块颜色也决定了),这样的话就化成了一维的方块摆放问题,即求f[n] ;
2.当摆放方案中存在相同方块连接时,其实一维的摆放确定了,二维的摆放也确定了,想一想,为什么?
在这里插入图片描述
用1 2 分别表示两种颜色,可以发现当出现连续方块时,其他行的方块的摆放也被固定了,相同颜色的上下行和其左右都必须时相反的颜色,这样第二种情况也就转化成一维问题了,即求f[m]-2 , 这里减去2是因为减去黑白相间的两种情况 (1212 和 2121),这两种在求第一种情况的时候就已经被计算了。

代码如下

#include<bits/stdc++.h>
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx=100000+5;
const int mod=1e9+7;
ll a[manx];
inline ll read(){
   ll s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
void put1(){ puts("Yes") ;}
void put2(){ puts("No") ;}
int main()
{
    ll n,m;
    n=read(),m=read();
    a[1]=2,a[2]=4;
    for(int i=3;i<=max(n,m);i++)
        a[i]=(a[i-1]+a[i-2])%mod;
    cout<<(a[n]+a[m]-2)%mod<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值