喵哈哈村的木星传说(四)
发布时间: 2017年4月11日 20:01 最后更新: 2017年4月11日 20:02 时间限制: 1000ms 内存限制: 128M
喵哈哈村有一个挂在空中的木星爷爷,每天晚上都讲一些故事。而星星同学,作为木星爷爷的听众,为了报答,于是每天晚上都会为他解决一个问题。
今天,星星同学要为木星爷爷解决这样一个问题:
小朋友喜欢在各种各样空间内跳。
现在,小朋友来到了一个二维平面。在这个平面内,如果邪教当前跳到了(x,y),那么他下一步可以选择跳到以下4个点:(x-1,y), (x+1,y), (x,y-1), (x,y+1)。
而每当小朋友到达一个点,他需要耗费一些体力,假设到达(x,y)需要耗费的体力用C(x,y)表示。
对于C(x,y),有以下几个性质:
1、若x=0或者y=0,则C(x,y)=1。
2、若x>0且y>0,则C(x,y)=C(x,y-1)+C(x-1,y)。
3、若x<0且y<0,则C(x,y)=无穷大。
现在,小朋友想知道从(0,0)出发到(N,M),最少花费多少体力(到达(0,0)点花费的体力也需要被算入)。
由于答案可能很大,只需要输出答案对10^9+7取模的结果。
本题包含若干组测试数据。
每行两个整数N,M,表示小朋友想到达的点。
满足 1<=N,M<=1e7
输出代价。
复制
1 2
6
题解:http://www.cnblogs.com/qscqesze/p/6695036.html
#include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
#define P 1000000007
ll n,m;
ll Pow(ll x,ll y)
{
ll res=1;
while(y)
{
if(y%2)
res=res*x%P;
x=x*x%P;
y/=2;
}
return res;
}
ll C(ll a,ll b)
{
if(b>a)
return 0;
if(b>a-b)
b=a-b;
ll s1=1,s2=1;
for(ll i=1;i<=b;i++)
{
s1=s1*(a-i+1)%P;
s2=s2*i%P;
}
return s1*Pow(s2,P-2)%P;
}
ll lucas(ll x,ll y)
{
return C(x/P,y/P)*C(x%P,y%P);
}
int main()
{
while(scanf("%lld%lld",&n,&m)!=EOF)
{
printf("%lld\n",(lucas(n+m+1,min(n,m))+max(n,m))%P);
}
return 0;
}