您的位置:首页 > 其它

Codeforces 559C Gerald and Giant Chess(组合数学+DP)

2018-02-06 10:17 405 查看

Codeforces 559C Gerald and Giant Chess(组合数学+DP)

题目大意:求一个矩形网格,从左上角到右下角不经过黑点的路径数

知识点:

组合数取模,在膜不超过十的五次方时可以用Lucas算法简化,本题中mod=10e9+7,所以不需要Lucas,直接预处理阶乘,在求组合数还要会求出逆元

如果Cmn%p表示为Lucas(m,n,p)如果Cnm%p表示为Lucas(m,n,p)

那么Cmn%p=Cm%pn%p∗Lucas(m/p,n/p,p)%p那么Cnm%p=Cn%pm%p∗Lucas(m/p,n/p,p)%p



3.AC代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long mod=1000000007;
struct node
{
long long x,y;
}point[2010];
bool cmp(node a,node b)
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
long long dp[2010];
long long  fac[200010];
void init()//预处理阶乘
{
fac[0]=1,fac[1]=1;
for(long long i=2;i<=200000;i++)
fac[i]=((fac[i-1]%mod)*(i%mod))%mod;
}
long long C(long long n,long long m)//求C(n,m)
{
long long ans=1,res=((fac[m]%mod)*(fac[n-m]%mod))%mod;
long long a=mod-2;
while(a)
{
if(a&1)
ans=((res%mod)*(ans%mod))%mod;
res=((res%mod)*(res%mod))%mod;
a=a>>1;
}
ans=((ans%mod)*(fac
%mod))%mod;
return ans;

}
int main()
{
long long h,w,n;
init();
while(~scanf("%lld%lld%lld",&h,&w,&n))
{
for(long long i=1;i<=n;i++)
scanf("%lld%lld",&point[i].x,&point[i].y);
point[n+1].x=h,point[n+1].y=w;
sort(point+1,point+n+1,cmp);
for(long long i=1;i<=n+1;i++)
{
dp[i]=C(point[i].x+point[i].y-2,point[i].x-1)%mod;
//printf("%lld\n",dp[i]);
for(long long j=1;j<i;j++)
{
if(point[j].x<=point[i].x&&point[j].y<=point[i].y)
{
dp[i]=((dp[i]-dp[j]*C(point[i].x-point[j].x+point[i].y-point[j].y,point[i].x-point[j].x))%mod+mod)%mod;

}
}

//.printf("%lld\n",dp[i]);
}
printf("%lld\n",dp[n+1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: