标签:复杂度 limits 动态 space sum long 计算 不能 efi
题目大意:给定一个H*W的棋盘,棋盘上只有N个格子是黑色的,其他格子都是白色的。在棋盘左上角有一个卒,每一步可以向右或者向下移动一格,并且不能移动到黑色格子中。求这个卒从左上角移动到右下角,一共有多少种可能的路线。$h,w\leq 10^5,k\leq 2000$。答案对$1e9+7$取模。
看到数据范围可以看出此题的时间复杂度和$k$有关,自然就想到每个障碍对答案产生了多少贡献。
考虑路径的组合意义:从左下角走到右下角,先不考虑有障碍的情况,显然是$\binom{n+m-2}{m-1}$,表示一共走$n+m-2$步,其中$m-1$步是向右走的。
现在考虑有障碍的情况:先将所有障碍以$x$为第一关键字,$y$以为第二关键字排序。我们设$f_i$表示从右下角走到第$i$个障碍的方案数。如果不考虑在它右下方的那些障碍,那么答案是$\binom{n+m-x_i-y_i}{m-y_i}$。有些路径可能经过在它右下方的障碍,所以要减去它们对答案的影响。所以有:
$f_i=\binom{n+m-x_i-y_i}{y-x_i}-\sum\limits_{j=i+1}^k f_j*\binom{x_j+y_j-x_i-y_i}{y_j-y_i}$
最终答案为:
$ans=\binom{n+m-2}{m-1}-\sum\limits_{i=1}^k f_i*\binom{x_i+y_i-2}{y_i-1}$
组合数可以$O(n)$预处理逆元,$O(1)$计算。时间复杂度$O(k^2+n\log n)$。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define int long long using namespace std; const int mod=1e9+7; const int maxn=500005; int n,m,k,inv[maxn],fac[maxn],ans,f[maxn]; struct node { int x,y; }a[maxn]; inline bool cmp(node x,node y){return x.x==y.x?x.y<y.y:x.x<y.x;} inline int calc(int x,int y) { return fac[x]*inv[y]%mod*inv[x-y]%mod; } inline int read() { int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if (ch==‘-‘) f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } inline int qpow(int x,int y) { int res=1; while(y) { if (y&1) res=(res*x)%mod; x=(x*x)%mod; y>>=1; } return res; } signed main() { n=read();m=read();k=read(); fac[0]=1; for (int i=1;i<=n+m;i++) fac[i]=(fac[i-1]*i)%mod; inv[n+m]=qpow(fac[n+m],mod-2); for (int i=n+m-1;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod; for (int i=1;i<=k;i++) a[i].x=read(),a[i].y=read(); sort(a+1,a+k+1,cmp); ans=calc(n+m-2,m-1); for (int i=k;i>=1;i--) { f[i]=calc(n+m-a[i].x-a[i].y,m-a[i].y);f[i]%=mod; for (int j=i+1;j<=k;j++) f[i]=(f[i]-f[j]*calc(a[j].x+a[j].y-a[i].x-a[i].y,a[j].y-a[i].y)%mod+mod)%mod; ans=(ans-f[i]*calc(a[i].x+a[i].y-2,a[i].y-1)%mod+mod)%mod; } printf("%lld",ans); return 0; }
【CF559C】Gerald and Giant Chess 题解(动态规划+组合数学)
标签:复杂度 limits 动态 space sum long 计算 不能 efi
原文地址:https://www.cnblogs.com/Invictus-Ocean/p/13661829.html