• CodeForces 348D Turtles(LGV定理)题解


    题意:两只乌龟从1 1走到n m,只能走没有'#'的位置,问你两只乌龟走的时候不见面的路径走法有几种

    思路:LGV定理模板。但是定理中只能从n个不同起点走向n个不同终点,那么需要转化。显然必有一只从1, 2走到 n - 1, m,另一只从2, 1走到 n, m - 1。

    代码:

    #include<cmath>
    #include<set>
    #include<map>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 3000 + 10;
    const int M = maxn * 30;
    const ull seed = 131;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1000000007;
    char mp[maxn][maxn];
    ll dp[maxn][maxn];
    ll e[5][5];
    ll guass(int n, ll p){
        ll ans = 1, f = 1;
        for(int i = 1; i <= n; i++){
            for(int j = i + 1; j <= n; j++){
                int x = i, y = j;
                while(e[y][i]){
                    ll t = e[x][i] / e[y][i];
                    for(int k = i; k <= n; k++)
                        e[x][k] = (e[x][k] - e[y][k] * t % p) % p;
                    swap(x,y);
                }
                if(x != i){
                    for(int k = 1; k <= n; k++)
                        swap(e[i][k], e[j][k]);
                    f = -f;
                }
            }
            ans = ans * e[i][i] % p;
            if(ans == 0) return 0;
        }
        return (ans * f + p) % p;
    }
    int main(){
        int n, m;
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++)
            scanf("%s", mp[i] + 1);
        memset(dp, 0, sizeof(dp));
        dp[1][2] = 1;
        for(int i = 1; i <= n; i++){
            for(int j = 2; j <= m; j++){
                if(i == 1 && j == 2) continue;
                if(mp[i][j] == '#') continue;
                dp[i][j] = 0;
                if(j - 1 >= 1 && mp[i][j - 1] != '#')
                    dp[i][j] += dp[i][j - 1];
                if(i - 1 >= 1 && mp[i - 1][j] != '#')
                    dp[i][j] += dp[i - 1][j];
                dp[i][j] = dp[i][j] % MOD;
            }
        }
        e[1][1] = dp[n - 1][m], e[1][2] = dp[n][m - 1];
        memset(dp, 0, sizeof(dp));
        dp[2][1] = 1;
        for(int i = 2; i <= n; i++){
            for(int j = 1; j <= m; j++){
                if(i == 2 && j == 1) continue;
                if(mp[i][j] == '#') continue;
                dp[i][j] = 0;
                if(j - 1 >= 1 && mp[i][j - 1] != '#')
                    dp[i][j] += dp[i][j - 1];
                if(i - 1 >= 1 && mp[i - 1][j] != '#')
                    dp[i][j] += dp[i - 1][j];
                dp[i][j] = dp[i][j] % MOD;
            }
        }
        e[2][1] = dp[n - 1][m], e[2][2] = dp[n][m - 1];
        printf("%lld
    ", guass(2, MOD));
        return 0;
    }
  • 相关阅读:
    Java核心技术 卷一 笔记四 库类的直接使用
    Java核心技术 卷一 笔记三 大数值及数组
    Java核心技术 卷一 笔记2 字符串的复制
    Java核心技术 卷一 笔记1
    修改css 样式后, hover事件 不生效
    修改 element ui input 输入框 样式不生效问题
    css3 计算属性
    Vue3 改动系列
    浏览器实现,向下滑动 鼠标滚轮,页面横向移动
    linux ceont0s7 vue 打包压缩图片 一直报错
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10816321.html
Copyright © 2020-2023  润新知