Codeforces #594 (Div. 1) A. Ivan the Fool and the Probability Theory(DP)

原题链接:https://codeforces.com/contest/1239/problem/A
大佬用来热身的小题
而我却迟迟想不出来

当n和m都为1的时候显然只有两种情况
当n为1,m不为1的时候或m为1,n不为1的时候
相当于在一行中每个方块进行黑白染色,且不能有三个连着的相同的颜色
d[i][1]表示第 i 块染白色的方案数,d[i][2]表示第 i 块染黑色的方案数
显然d[1][1]=1 d[1][2]=1 d[2][1]=2 d[2][2]=2
前两块怎么染都无所谓的,再往后
d[i][1]=d[i-1][2]+d[i-2][2]
d[i][2]=d[i-1][1]+d[i-2][1]
第 i 块染白色的方案数相当于第 i-1 块染黑色的方案数 加上 第 i-2 块染黑的方案数(仔细思考一下)

当n和m都大于2时转化一下也就相当于一行中染色
注意有重复的情况

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

ll d[200005][3],f[200005][3];
ll ans=0,mod=1e9+7;

int main()
{
    ll n,m;
    cin>>n>>m;
    if(n==1&&m==1){cout<<"2"<<endl;return 0;}
    d[1][1]=1;d[1][2]=1;
    d[2][1]=2;d[2][2]=2;
    for(int i=3;i<=n;i++)
    {
        d[i][1]=(d[i-1][2]+d[i-2][2])%mod;
        d[i][2]=(d[i-1][1]+d[i-2][1])%mod;
    }
    f[1][1]=1;f[1][2]=1;
    f[2][1]=2;f[2][2]=2;
    for(int i=3;i<=m;i++)
    {
        f[i][1]=(f[i-1][2]+f[i-2][2])%mod;
        f[i][2]=(f[i-1][1]+f[i-2][1])%mod;
    }
    if(n==1)
    {
        cout<<(f[m][1]+f[m][2])%mod<<endl;
        return 0;
    }
    if(m==1)
    {
        cout<<(d[n][1]+d[n][2])%mod<<endl;
        return 0;
    }
    cout<<(d[n][1]+d[n][2]+f[m][1]+f[m][2]-2)%mod<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值