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;
    }
    
  • 相关阅读:
    Mybatis中#{}和${}传参的区别
    笔记摘抄 —— shiro学习篇
    使用Spring的Testcase的单元测试的写法
    【转】FreeMarker学习笔记
    破解Pycharm,IDEA,PhpStrom等系列产品的,有关JetbrainsCrack的使用方法
    Python的字符串
    python的变量
    python开头注释
    h5-动画小案例-滚动展示
    h5-钟表动画案例
  • 原文地址:https://www.cnblogs.com/sdlang/p/13922541.html
Copyright © 2011-2022 走看看