2276: 跳一跳(思维 + dp + 组合数学)

题目描述

今天跳跳去公园游玩,第一个游戏就难倒了跳跳,游戏规则是跳跳站在一个面积无限大的矩形土地上,开始时跳跳在左上角(即第一行第一列),每一次跳跳都可以选择一个右下方格子,并瞬间跳过去(如从下图中的红色格子能直接跳到蓝色格子),求跳到第n行第m列的格子有多少种方案,答案对1000000007取模。

输入

单组测试数据。 

两个整数n,m(2<=n,m<=100000)

输出

一个整数表示方案数。

样例输入

4 5

样例输出

10

建议大家先看一下我的博客:博客一博客二

两个博客中题目差不多一致但是实现不一样(数据的缘故),但是博客一给我们提供了一个很好的思路去解决这个问题,对于此题我们可以用dp证明

dp[i][j] = dp[i-1][j] + dp[i][j-1];(我的博客中提到过这个就是杨辉大三角)

但是由于数据的缘故没办法用dp进行coding,那怎么办呢?博客二有给我们提供了一个好的思路去解决,使用逆元

AC:代码

 
 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 200000+5;
#define mod 1000000007
typedef long long ll;

ll fac[maxn];

void get_fac(){
	fac[0] = fac[1] = 1;
	for(int i = 2;i<maxn;i++){
		fac[i] = (fac[i-1]*i)%mod;
	}
}

ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
	if(b == 0){
		x = 1;
		y = 0;
		return a;
	}
	ll temp = ex_gcd(b,a%b,y,x);
	y -= x*(a/b);
	return temp;
}

ll inv(ll s)
{
	ll x,y;
	ex_gcd(s,mod,x,y);
	return (x%mod+mod)%mod;
}

int main()
{
	ll n,m,a,b;
	get_fac();
	scanf("%lld %lld",&n,&m);
	a = n+m-4;
	b = n-2;
	printf("%lld\n",(fac[a]%mod*inv(fac[a-b])%mod*inv(fac[b])%mod+mod)%mod);
	
	return 0;
}



猜你喜欢

转载自blog.csdn.net/acer12138/article/details/80318290
今日推荐