喵哈哈村的木星传说(四)-(卢卡斯定理)

本文介绍了一个关于小朋友从(0,0)出发到(N,M)的二维平面上跳跃的问题,目的是找到最少消耗体力的路径,并给出了使用组合数学和模运算求解的方法。

喵哈哈村的木星传说(四)

发布时间: 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值