题意:
曾经有一道叫做迷雾森林的题目,然而牛牛认为地图中的障碍太多,实在是太难了,所以删去了很多点,出了这道题。
牛牛给出了一个n行m列的网格图
初始牛牛处在最左下角的格点上(n+1,1),终点在右上角的格点(1,m+1)
现在它想知道,从起点走到终点,只能向上或向右走,一共有多少种走法呢?
需要注意的是,除了起点和终点外,其它的每个格点都有可能有障碍,无法通过。
请注意格子与格点的区别
题解:
参考博客
对于 n,m<=1000 的点:DP
对于 n,m<=100000 的点,因为k很小,考虑使用容斥原理,我们定义一个work函数,work是指右移a次上移b次有多少种移法
假设只有一个点(x,y)不能走,总方案是C(m+n,n),减去经过这个点方案C(x+y,x) * C(n-x+n-y,n-x)
即 C(m+n,n)- C(x+y,x) * C(n-x+n-y,n-x)
如果有多个障碍点的话,我们考虑什么样的点彼此会共同影响,
图中绿色为障碍点,蓝色为路线,我们不难发现当点与点之间存在偏序关系的时候,就会彼此共同影响,如何找偏序关系,当
(x[j]>=x[i]&&y[j]>=y[i])(i是左下方的点,j是右上方的点)时说明满足条件
代码:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL n,m,k,s,t;
bool f[1005][1005];
LL dp[1005][1005];
LL x[10],y[10];
LL mod=998244353;
LL ksm(LL a) {
LL b=mod-2;
LL ans=1;
while(b) {
if(b&1)
ans=(a*ans)%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
LL ni[100005];
void csh() {
for(LL i=1; i<=100000; i++)
ni[i]=ksm(i);
}
LL C(LL a,LL b) {
LL a1=1;
for(LL i=b; i>=b-a+1; i--)
a1=a1*i%mod;
for(LL i=1; i<=a; i++)
a1=(a1*ni[i])%mod;
return a1;
}
LL work(LL a,LL b) {
return C(a,a+b);
}
int main() {
cin>>n>>m&g
京公网安备 11010502036488号