1118 机器人走方格 DP 或者组合数+逆原

来源:互联网 发布:淘宝永久封店怎么办 编辑:程序博客网 时间:2024/06/08 13:28
M * N的方格,一个机器人从左上走到右下,只能向右或向下走。有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果。
Input
第1行,2个数M,N,中间用空格隔开。(2 <= m,n <= 1000)
Output
输出走法的数量。
Input示例
2 3
Output示例

3



第一种做法是用dp,dp【i】【j】=dp[i-1][j]+dp[i][j-1]

需要注意的是dp[1][1-m] 和dp[1-n][1] 全部都设为1,因为走到那些点都只有一个走法能到达!!!!!

、之后从i=2开始枚举,这个点十分重要


第二种做法是组合数+逆原。

我们需要走n-m-2步,我们要从n-m-2步中挑选n-1步走横线。所以就是求C(n-m-2,n-1),不过需要注意的是,我们在组合数过程中肯定要用的除法,但是

我们不能用除法做,所以需要用到逆原,转变成乘法


法一:

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL;
int const mod=1000000000+7;
LL dp[1005][1005];
int main()
{
    int n,m;
    scanf("%d %d",&m,&n);
    for(int i=1;i<=n;i++)
    {
        dp[1][i]=1;


    }
        for(int i=1;i<=m;i++){
        dp[i][1]=1;


    }


    for(int i=2;i<=m;i++){
        for(int j=2;j<=n;j++){
            dp[i][j]=dp[i][j-1]%mod+dp[i-1][j]%mod;


        }
    }
        //printf("%I64d\n",dp[127][17]%mod);


    int res=dp[m][n]%mod;
    printf("%d\n",res);




    return 0;
}



法二:

#include<iostream>  
#include<cstdio>  
#include<algorithm>  
#include<cmath>  
using namespace std;  
const int mod=1e9+7;  
typedef long long ll;  
//返回d=gcd(a,b);和对应于等式ax+by=d中的x,y  
ll extend_gcd(ll a,ll b,ll &x,ll &y)  
{  
    if(a==0&&b==0) return -1;//无最大公约数  
    if(b==0){x=1;y=0;return a;}  
    ll d=extend_gcd(b,a%b,y,x);  
    y-=a/b*x;  
    return d;  
}  
//*********求逆元素*******************  
//ax = 1(mod n)  
ll mod_reverse(ll a,ll n)  
{  
    ll x,y;  
    ll d=extend_gcd(a,n,x,y);  
    if(d==1) return (x%n+n)%n;  
    else return -1;  
}  
  
ll c(ll m,ll n)  
{  
    ll i,j,t1,t2,ans;  
    t1=t2=1;  
    for(i=n;i>=n-m+1;i--) t1=t1*i%mod;  
    for(i=1;i<=m;i++) t2=t2*i%mod;  
    return  t1*mod_reverse(t2,mod)%mod;  
}  
  
int main()  
{  
    ll n,m,ans;  
    cin>>m>>n;  
    ans=c(min(m-1,n-1),m+n-2);  
    cout<<ans<<endl;  
    return 0;  
}   


阅读全文
0 0