zoukankan      html  css  js  c++  java
  • 洛谷 P5304 [GXOI/GZOI2019]旅行者

    给定一个(n imes m)(n,mle 10^5))的棋盘,棋盘上只有(k)(kle2000))个格子是黑色的,其他格子都是白色的。在棋盘左上角有一个卒,每一步可以向右或者向下移动一格,并且不能移动到黑色格子中。求这个卒从左上角移动到右下角,一共有多少种可能的路线。

    我们发现(n,m)很大,不好下手,所以考虑从(k)入手,那么方案数就是总方案数减去走到这个黑点的方案数乘从这个黑点走到终点的方案数。

    总方案数非常好求,就是(egin{pmatrix}n+m-2\n-1end{pmatrix})

    然后考虑设(f_i)表示从起点走到第(i)个黑点且不经过其他黑点的方案数,那么这个显然也是可以按刚才那个方法容斥求得的,于是有如下转移方程:

    [f_i=egin{pmatrix}x_i+y_i-2\x_i-1end{pmatrix}-sum_{j=1}^kf_jegin{pmatrix}x_i-x_j+y_i-y_j\x_i-x_jend{pmatrix}[x_ige x_j,y_ige y_j] ]

    (x_ige x_j,y_ige y_j)可以通过排序轻松处理出来。

    于是最后答案就是:

    [egin{pmatrix}n+m-2\n-1end{pmatrix}-sum_{i=1}^kf_iegin{pmatrix}n-x_i+m-y_i\n-x_iend{pmatrix} ]

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    const int N = 2e5;
    const int p = 1e9 + 7;
    using namespace std;
    int n,m,k,fac[N + 5],inv[N + 5],ans,f[N + 5];
    struct black
    {
    	int x,y;
    }a[N + 5];
    int C(int n,int m)
    {
    	return 1ll * fac[n] * inv[n - m] % p * inv[m] % p;
    }
    bool cmp(black a,black b)
    {
    	if (a.x == b.x)
    		return a.y < b.y;
    	return a.x < b.x;
    }
    int main()
    {
    	scanf("%d%d%d",&n,&m,&k);
    	fac[0] = 1;
    	for (int i = 1;i <= N;i++)
    		fac[i] = 1ll * fac[i - 1] * i % p;
    	inv[1] = 1;
    	for (int i = 2;i <= N;i++)
    		inv[i] = 1ll * (p - p / i) * inv[p % i] % p;
    	inv[0] = 1;
    	for (int i = 1;i <= N;i++)
    		inv[i] = 1ll * inv[i - 1] * inv[i] % p;
    	ans = C(n + m - 2,n - 1);
    	for (int i = 1;i <= k;i++)
    		scanf("%d%d",&a[i].x,&a[i].y);
    	sort(a + 1,a + k + 1,cmp);
    	for (int i = 1;i <= k;i++)
    	{
    		f[i] = C(a[i].x + a[i].y - 2,a[i].x - 1);
    		for (int j = 1;j < i;j++)
    			if (a[j].x <= a[i].x && a[j].y <= a[i].y)
    				f[i] -= 1ll * f[j] * C(a[i].x - a[j].x + a[i].y - a[j].y,a[i].x - a[j].x) % p,f[i] %= p;
    		ans -= 1ll * f[i] * C(n - a[i].x + m - a[i].y,n - a[i].x) % p;
    		ans %= p;
    	}
    	cout<<(ans + p) % p<<endl;
    	return 0;
    }
    
  • 相关阅读:
    leetcode 13. Roman to Integer
    python 判断是否为有效域名
    leetcode 169. Majority Element
    leetcode 733. Flood Fill
    最大信息系数——检测变量之间非线性相关性
    leetcode 453. Minimum Moves to Equal Array Elements
    leetcode 492. Construct the Rectangle
    leetcode 598. Range Addition II
    leetcode 349. Intersection of Two Arrays
    leetcode 171. Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/sdlang/p/13922541.html
Copyright © 2011-2022 走看看