zoukankan      html  css  js  c++  java
  • 8.10-Day2T2 吃喝大法好

    题目大意

    略...

    题解

    开始两个人一定是一个向右走一个向下走,向右走的人最终会走到(n-1,m),向下走的人一定会走到(n,m-1)。
    那么不考虑重复的话总的路径数就是从(1,2)到(n-1,m)的路径数*从(2,1)到(n,m-1)的路径数,这个用 dp 就可以解决,dp 方程是dp[ i ][ j ] = dp[ i - 1 ][ j ] + dp[ i ][ j - 1 ]
    其中 dp[i][j]表示从起点到(i,j)的方案数。
    考虑两条相交的路径,找到第一个交点,然后让这两个人在这个交点相交后走对方的路径。也就是第一步向下的人走到(n-1,m),另一个人走到(n,m-1)。
    对于任何一条相交的路径,我们都可以进行如上转化,所以相交路径的方案数就是从(1,2)到(n,m-1)的路径数*从(2,1)到(n-1,m)的路径数.。同样用 dp 解决。
     
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #define ll long long
    using namespace std;
    
    inline int read()
    {
        int sum = 0,p = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-')
                p = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (sum *= 10) += ch - '0';
            ch = getchar();
        }
        return sum * p;
    }
    
    const ll mod = 5462617;
    int n,m;
    int mp[2009][2009];
    ll dp[2009][2009]; 
    ll ans1,ans2,ans3,ans4;
    
    int main()
    {
        freopen("path.in","r",stdin);
        freopen("path.out","w",stdout);
        n = read(),m = read();
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
            {
                scanf("%1d",&mp[i][j]);
                mp[i][j] ^= 1;
            }
        if(mp[2][1] == 0 || mp[1][2] == 0)
        {
            puts("0");
            return 0;
        }
        dp[1][1] = 1;
        for(int i = 2; i <= n; i++)
            for(int j = 1; j <= m; j++)
            {
                if(mp[i][j])
                    dp[i][j] = (dp[i - 1][j] +dp[i][j - 1])%mod;
            }
        ans1 = dp[n][m - 1];
        ans2 = dp[n - 1][m];
        memset(dp,0,sizeof(dp));
        dp[1][1] = 1;
        for(int i = 1;i <= n;i++)
            for(int j = 2;j <= m;j++)
            {
                if(mp[i][j])
                    dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % mod;
            }
        ans3 = dp[n][m - 1];
        ans4 = dp[n - 1][m];
        printf("%lld",(ans1 * ans4 % mod - ans2 * ans3 % mod + mod)%mod);
        return 0;
    }
    View Code
     
  • 相关阅读:
    Acwing 164 可达性统计 (拓扑排序+bitset)
    STL-bitset的基本用法
    Acwing 115 给树染色 (贪心)
    Acwing 112 雷达设备 (贪心)
    Acwing 110 畜栏预定 (贪心+stl)
    Acwing 110 防晒 (贪心算法)
    Acwing 七夕祭 (前缀和+中位数+思维)
    Acwing 103 电影 (map)
    USACO 最佳牛围栏 (二分答案+前缀和+双指针)
    Acwing 101 最高的牛 (差分数组)
  • 原文地址:https://www.cnblogs.com/darlingroot/p/11345258.html
Copyright © 2011-2022 走看看