本文主要是介绍mcpc2017 Hopscotch 组合数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
5095: Hopscotch
题目描述
You dislike making small hops though. You’ve decided that for every hop you make between two lattice points, the x-coordinate must increase by at least X and the y-coordinate must increase by at least Y .
Compute the number of distinct paths you can take between (0, 0) and (N, N) that respect the above constraints. Two paths are distinct if there is some lattice point that you visit in one path which you don’t visit in the other.
Hint: The output involves arithmetic mod 109+ 7. Note that with p a prime like 109+ 7, and x an integer not equal to 0 mod p, then x(xp−2) mod p equals 1 mod p.
输入
输出
样例输入
7 2 3
样例输出
9
题目大意:给出n,x,y,从(0,0)到(n,n) 行坐标的增加每次不小于x,列坐标的增加每次不小于y。
题目分析:如果只看一维的可以把这个题看成把n个球分成t(1~n/x)份,每一份的个数都不能小于x,可以先向每一份分上x-1,就可以看成把剩下的分成t份有多少种分发,C(n-t*(x-1)-1 , t-1),这就是只看一维。
如果看成二维就是 : C(n-t*(x-1)-1 , t-1)*C(n-t*(y-1)-1 , t-1)。最后把所有结果加起来就可以。
还有一点要注意的是组合数不能直接求,要先打表,而且数很大,组合数求的时候要用到逆元。
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=1e6+7;
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[maxn],inv[maxn];ll init(){fac[0]=1;for (int i=1;i<maxn;i++)fac[i]=fac[i-1]*i%mod;inv[maxn-1]=qpow(fac[maxn-1],mod-2);for (int i=maxn-2;i>=0;i--)inv[i]=inv[i+1]*(i+1)%mod;return 0;
}
ll C(ll n,ll m){if (n<m) return 0;return fac[n]*inv[m]%mod*inv[n-m]%mod;
}int main()
{ll n,x,y;init();scanf("%lld%lld%lld",&n,&x,&y);ll m=min(n/x,n/y);ll ans=0;for(ll i=1;i<=m;i++){ans=(ans+C(n-i*(x-1)-1,i-1)%mod*C(n-i*(y-1)-1,i-1)%mod)%mod;}printf("%lld\n",ans);return 0;
}
这篇关于mcpc2017 Hopscotch 组合数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!