zoukankan      html  css  js  c++  java
  • [CodeForces][计数DP] Gerald and Giant Chess

    题面

    // 首先看范围不太可直接暴力解
    // 考虑 f[i] 为经过第 i 个黑点的方案数,
    // 直接计算比较难算,可以从总方案减去不合法方案。
    // f[i] = C(xi-1, xi+yi-2) - sum(f[j] * C(xi-xj, xi+yi-xj+yj));
    
    # include <iostream>
    # include <cstdio>
    # include <algorithm>
    # define LL long long
    # define MAXN 300005
    
    const LL MOD = 1e9+7;
    
    struct point{
    	int x, y;
    }p[MAXN];
    LL inv[MAXN], fac[MAXN];
    LL f[MAXN];
    
    bool CmpP(point x, point y){
    	return x.x == y.x ? x.y < y.y : x.x < y.x;
    }
    
    LL QPow(LL x, LL y){
    	LL ans = 1, base = x % MOD;
    	while(y){
    		if(y & 1){
    			(ans *= base) %= MOD;
    		}
    		(base *= base) %= MOD;
    		y >>= 1;
    	}
    	return ans;
    }
    
    LL Combine(LL m, LL n){
    	if(m > n){
    		return 0;
    	}
    	return (((fac[n] * inv[n-m]) % MOD) * inv[m]) % MOD;
    }
    
    int main(){
    	int h, w, n;
    	scanf("%d%d%d", &h, &w, &n);
    
    	for(int i = 1; i <= n; i++){
    		scanf("%d%d", &p[i].x, &p[i].y);
    	}
    	p[++n] = (point){h, w};
    
    	std::sort(p+1, p+n+1, CmpP);
    
    	fac[0] = inv[0] = 1;
    	for(int i = 1; i <= MAXN; i++){
    		fac[i] = (fac[i-1]*i) % MOD;
    		inv[i] = QPow(fac[i], MOD-2);
    	}
    
    	for(int i = 1; i <= n; i++){
    		f[i] = Combine(p[i].x-1, p[i].x+p[i].y-2);
    	}
    
    	for(int i = 1; i <= n; i++){
    		for(int j = 1; j <= i-1; j++){
    			if(p[j].x > p[i].x || p[j].y > p[i].y){
    				continue;
    			}
    
    			f[i] -= f[j]*Combine(p[i].x-p[j].x, p[i].x+p[i].y-p[j].x-p[j].y);
    			(f[i] += MOD) %= MOD;
    		}
    	}
    
    	printf("%lld", (f[n]+MOD)%MOD);
    
    	return 0;
    }
    
  • 相关阅读:
    [读书计划]2015读书计划
    [整理]iOS开发学习
    nginx配置
    Nginx的使用
    Spring
    JSP的使用以及EL和JSTL的使用
    关于linux安装tomcat和mysql
    linux常用操作(安装jdk配置环境变量)
    redis的安装与使用
    Mybatis
  • 原文地址:https://www.cnblogs.com/Foggy-Forest/p/13619539.html
Copyright © 2011-2022 走看看