A Path Plan(非降路径和Lindström–Gessel–Viennot定理)

                                           A Path Plan

                                                              时间限制: 1 Sec  内存限制: 128 MB
                                                                             提交: 61  解决: 28
                                                               [提交] [状态] [讨论版] [命题人:admin]

题目描述

WNJXYK hates Destinys so that he does not want to meet him at any time. Luckily, their classrooms and dormitories are at different places. The only chance for them to meet each other is on their way to classrooms from dormitories. 
To simple this question, we can assume that the map of school is a normal rectangular 2D net. WNJXYK’s dormitory located at (0,y_1) and his classroom located at (x_1,0). Destinys’s dormitory located at (0,y_2) and his classroom is located at (x_2,0). On their way to classrooms, they can do two kinds of movement : (x,y)→(x,y-1) and (x,y)→(x+1,y). 
WNJXYK does not want to meet Destinys so that he thinks that it is not safe to let his path to classroom from dormitory has any intersect point with Destinys ‘s. And then he wonders how many different paths for WNJXYK and Destinys arriving their classrooms from dormitories safely.

输入

The input starts with one line contains exactly one positive integer T which is the number of test cases.
Each test case contains one line with four positive integers x1,x2,y1,y2 which has been explained above.

输出

For each test case, output one line containing “y” where y is the number of different paths modulo 10^9+7.

样例输入

3
1 2 1 2
2 3 2 4
4 9 3 13

样例输出

3
60
16886100

T≤1000
x1<x2,y1<y2
0 < x1,x2,y1,y2≤100000
For Test Case 1, there are following three different ways.

非降路径

就是给定一个起点(0,0)和终点(m,n),然后只能向右或者向上走。

非降路径问题转换为组合数可以认为总共有n+m种选择,从中选出m步向右走,或者选择n步向上走,则可得路径的方案数为C_{n+m}^{n}C_{n+m}^{m}

Lindström–Gessel–Viennot定理

详见维基百科:https://en.wikipedia.org/wiki/Lindstr%C3%B6m%E2%80%93Gessel%E2%80%93Viennot_lemma

这里只了解应用即可

对于一张无边权的DAG图,给定n个起点和对应的n个终点,这n条不相交路径的方案数为

其中 ai 代表路径的起点 bi 代表路径的终点 e(ai,bj) 代表ai到bj的方案数。

题意:给你x1,x2,y1,y2,(x1<x2,y1<y2)问你从x1到y1的同时x2到y2不想交的路径有多少

题解  a1=(a,0)   b1=(0,c)

        a2=(b,0)    b2=(0,d)

通过公式转化为行列式

         e(a1,b1)    e(a1,b2)

         e(a2,b1)    e(a2,b2)

然后行列式计算就行了,注意预处理一下逆元,否则会超时

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<deque>
#include<ctype.h>
#include<map>
#include<set>
#include<stack>
#include<string>
#define INF 0x3f3f3f3f
#define FAST_IO ios::sync_with_stdio(false)
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAX=1e6+10;
const long long mod=1e9+7;
typedef long long ll;
using namespace std;
#define gcd(a,b) __gcd(a,b)
inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
ll fac[MAX];
ll inv[MAX];
void init()
{
    fac[0]=1;
    for (int i=1;i<MAX;i++)
        fac[i]=fac[i-1]*i%mod;
    inv[MAX-1]=qpow(fac[MAX-1],mod-2);
    for (int i=MAX-2;i>=0;i--)
        inv[i]=inv[i+1]*(i+1)%mod;

}
int C(ll n,ll m)
{
    return ((fac[n]*inv[m]%mod)%mod*inv[n-m]%mod)%mod;
}
int main()
{
    init();
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll a,b,c,d;
        scanf("%lld%lld%lld%lld",&a,&b,&c,&d);

        ll temp1=(C(a+c,a)%mod*C(b+d,b)%mod)%mod;
        ll temp2=(C(a+d,a)%mod*C(b+c,b)%mod)%mod;

        ll temp=(temp1-temp2+mod)%mod;

        printf("%lld\n",temp);

    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41021816/article/details/82430011
今日推荐