ZOJ 3624 Count Path Pair(组合计数)

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove

题目:从A到D与从B到C的路径中不相交的有多少条。

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3624

看似比较复杂,解法也很独特。不相交的难求,那就求相交的。

总路径数是C(M+N,M)*C(Q+M-P,Q)。

然后相交的地方肯定是B与C构成的矩形当中。

我们可以考虑A到C以及B到D,他们的路径必定有相交的,而且相交的位置必定也在矩形当中。

而且相交之后你可以考虑成从A到C的路径改为从交点到D,就样就完成了转化。

结果便是C(M+N,M)*C(Q+M-P,Q)-C(N+M-P,N)*C(M+Q-M);

#include<iostream>
#include<fstream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<sstream>
#include<ctime>
#include<cassert>
#define LL long long
#define eps 1e-8
#define inf 999999.0
#define zero(a) abs(a)<eps
#define N 20
#define MOD 100000007
#define pi acos(-1.0)
using namespace std;
//以下为求逆元
LL extend_gcd(LL a,LL b,LL &x,LL &y){
    if(b==0){x=1;y=0;return a;}
    LL gcd=extend_gcd(b,a%b,x,y);
    LL t=x;
    x=y;y=t-a/b*x;
    return gcd;
}
LL Get_Inverse(LL num){
    LL x,y;
    extend_gcd(num,MOD,x,y);
    return (x%MOD+MOD)%MOD;
}
//计算C(N,M)
LL cal(LL n,LL m){
    LL t1=1,t2=1;
    for(LL i=n;i>m;i--){
        t1=(t1*i)%MOD;
        t2=(t2*(i-m))%MOD;
    }
    return t1*Get_Inverse(t2)%MOD;
}
int main(){
    LL m,n,p,q;
    while(scanf("%lld%lld%lld%lld",&m,&n,&p,&q)!=EOF)
        printf("%lld\n",((cal(m+n,m)*cal(q+m-p,q)-cal(n+m-p,n)*cal(m+q,m))%MOD+MOD)%MOD);
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值