[海豹海边爆]Daimayuan467

原题链接:路径计数2 - 题目 - Daimayuan Online Judge

解题思路:按照题目中两种移动方式,从一个点移动到另一个点的路径数可以用组合数公式快速计算得出。如果从点(0,0)移动到点(n,m),一共需要走n+m步,其中n步为向下。那么在n+m步中选择n步,得到的结果就是在不同步数下选择的向下移动,即路径数。

而题目中有一些不可通行的点,那么就要在总路径数中减去到达这些点的路径数。而不可通行的点之间,也有一些重复路径,那么也需要将重复的路径减掉。这两步的操作是一样的,因为减去重复路径,等同于减去所有到达其他点再出发到达该点的路径。

然后减去包含的点只需要先对存储点的数组进行排序,越靠近(0,0)的在前面。然后只需要O(n^2)的复杂度就可以减去重复路径了。

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
long long fact[10000010],inv[10000010];//fact存阶乘,inv存对应逆元 
long long n,m,sum[1000010];//sum为到达不同点的不重复路径数 
struct qwq{//存点 
	long long x,y;
} p[1000010];
long long int_pow(long long x,long long k){//快速幂 
    long long ans=1 ;
    while(k){
        if(k&1) ans=ans*x%mod;
        k=k>>1;
        x=(x*x)%mod;
    }
    return ans ;
}
void pre_work(){//预处理阶乘与逆元 
	fact[0]=1;
	fact[1]=1;
	for(long long i=2;i<=10000000;i++) fact[i]=fact[i-1]*i,fact[i]%=mod;
	inv[10000000]=int_pow(fact[10000000],mod-2);
	for(long long i=9999999;i>0;i--) inv[i]=inv[i+1]*(i+1)%mod;
	inv[0]=1;
	return;
}
int cmp(qwq a,qwq b) {//sort排序的判断函数 
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
int main(){
	pre_work();
	cin>>n>>m;//输入
	for(int i=0;i<m;i++){ 
		cin>>p[i].x>>p[i].y;
	}
	
	p[m].x=n;//把重点也作为不可通行点处理 
	p[m].y=n;
	m++;
	
    sort(p,p+m,cmp);//排序
	 
    long long x1,y1,x2,y2;//缓存数据,防止重复计算 
    for(int i=0;i<m;i++){//遍历每个不可通行点 
        x1=p[i].x-1;
		y1= p[i].y-1;
        sum[i]=fact[x1+y1]*inv[x1]%mod*inv[y1]%mod;//组合数公式计算没有其他点干扰的路径数 
        for(int j=0;j<i;j++) {//查是否有重复路径 
            if(p[j].x<=p[i].x&&p[j].y<=p[i].y) {//如果有则减去通过那些点的路径 
                x2=x1-p[j].x+1;
				y2=y1-p[j].y+1;
                sum[i]=(sum[i]-fact[x2+y2]*inv[x2]%mod*inv[y2]%mod*sum[j]%mod)%mod;
                if(sum[i]<=0) sum[i]=(sum[i]+mod)%mod;
            }
        }
    }
    
	cout<<sum[m-1];
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值