【题解】CF559C C. Gerald and Giant Chess(容斥+格路问题)
【题解】CF559C C. Gerald and Giant Chess(容斥+格路问题)
55336399 | Practice: Winlere | 559C - 22 | GNU C++11 | Accepted | 186 ms | 1608 KB | 2019-06-09 17:03:21 | 2019-06-09 17:03:21 |
---|---|---|---|---|---|---|---|---|
一道小水题(为什么2400??我为什么之前被一道2200锤QAQ)
有个很显然的公式,在组合数学那本书上面也有。
从坐标\((0,0)\)到坐标\((x,y)\)总共有\({x+y}\choose x\)种不回头走的办法。
证明显然,考虑从\((0,0)\)到\((x,y)\)一定要走\(x+y\)步,从中随意抽出\(x\)步向\(x\)正半轴走就构成了我们的路径条数。记为\(G(x,y)\)吧
\(dp(i,j)\)表示从原点到此有多少条合法的路径。转移从所有可以阻挡住他的点来。
我会出一篇总结组合数学那本书上面的结论的博客,密码:orzyyb。
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define x first
#define y second
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=2e5+5;
const int mod=1e9+7;
int fac[maxn],inv[maxn],dp[2001],n;
pair < int , int > data[2001];
inline int ksm(int base,const int&p){register int ret=1;
for(register int t=p;t;t>>=1,base=1ll*base*base%mod)if(t&1) ret=1ll*ret*base%mod;
return ret;
}
inline int c(const int&n,const int&m){return n<m?0:1ll*fac[n]*inv[m]%mod*1ll*inv[n-m]%mod;}
inline int grid(const int&x,const int&y){return c(x+y,x);}
int main(){
fac[0]=inv[0]=1;
for(register int t=1;t<maxn;++t) fac[t]=1ll*fac[t-1]*t%mod,inv[t]=ksm(fac[t],mod-2);
data[0].x=qr();data[0].y=qr();n=qr();
for(register int t=1;t<=n;++t) data[t].x=qr(),data[t].y=qr();
sort(data,data+n+1);
for(register int t=0;t<=n+1;++t){
dp[t]=grid(data[t].x-1,data[t].y-1);
for(register int i=0;i<t;++i){
dp[t]=(dp[t]-1ll*dp[i]*grid(data[t].x-data[i].x,data[t].y-data[i].y)%mod)%mod;
if(dp[t]<0) dp[t]+=mod;
}
}
cout<<dp[n]<<endl;
return 0;
}
博客保留所有权利,谢绝学步园、码迷等不在文首明显处显著标明转载来源的任何个人或组织进行转载!其他文明转载授权且欢迎!