• 【AtCoder ABC 145 D】Knight


    题目大意:

      你现在在位置 $(0,0)$,每一次可以选择以下两种方式的任意一种移动:

    • 向下走一格,向右走两格;
    • 向下走两格,向下走一格。

      求可以到达 $(x,y)$ 的方案总数,对 $10^9+7$ 取模。

    解析:

      这道题给了一个很好的限制:只能向右、向下走。

      观察题目,可以发现如果 $3 mid x+y$,那么方案数是 $0$,因为每一次转移都会使得横纵坐标和加上 $3$。

      所以,我们只需列一个方程组,就可以求出向下走 $1$ 格并向右走 $2$ 格的方案次数,与向下走 $2$ 格且向下走 $1$ 格的方案次数。

      知道了分别转移的次数,我们就要枚举顺序。

      假设第一种方式转移 $a$ 次,第二种方式转移 $b$ 次。

      那么,问题就简化成这个样子:

        有 $a$ 个 $1$ 与 $b$ 个 $0$ 进行组合,可以制造出多少个不同的数字串 ?

      答案显而易见,是 $large{inom {a+b} a}$ 或 $large{inom {a+b} b}$。

      当然,要注意本题有取模,求组合数时要预处理逆元。

    代码:

    #include <cstdio>
    #define MOD 1000000007
    #define INF 1e9
    #define eps 1e-6
    typedef long long ll;
    
    ll x, y, xx, yy, inv[2000010], prod[2000010], ans;
    
    int main(){
    
        scanf("%lld%lld", &x, &y);
        if((x + y) % 3){
            puts("0");
            return 0;
        }
        xx = x - (x + y) / 3;
        yy = y - (x + y) / 3;
        if(x < 0 || y < 0)
            puts("0");
        else{
            inv[0] = inv[1] = 1;
            for(ll i = 2; i <= (xx + yy); i++)
                inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;
            for(ll i = 2; i <= (xx + yy); i++)
                inv[i] = inv[i - 1] * inv[i] % MOD;
            prod[0] = 1;
            for(ll i = 1; i <= (xx + yy); i++)
                prod[i] = prod[i - 1] * i % MOD;
            ans = prod[xx + yy] * inv[xx] % MOD * inv[yy] % MOD;
            printf("%lld
    ", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    安装python3的详细教程
    MySQL中的各种引擎
    MySQL的语句执行顺序
    MySQL 5.7新增加的json数据类型
    MySQL5.6 PERFORMANCE_SCHEMA 说明
    MySQL中的sys系统数据库是干嘛的
    MySQL中information_schema数据库是干啥的
    mysql中You can’t specify target table for update in FROM clause错误解决方法
    win10 localhost 解析为::1 的解决办法
    python 中对象is和==是怎么比较的
  • 原文地址:https://www.cnblogs.com/zengpeichen/p/11992399.html
Copyright © 2020-2023  润新知