定理(Lindström–Gessel–Viennot lemma)很简单:

学的时候忘了大的行列式怎么算的了。。

然后就可以写题了:

第一道:CodeForces-348D(链接https://vjudge.net/problem/CodeForces-348D)

题意给你个n*m的方阵,有一些点无法通过,然后求从(1,1)到(n,m)走两条路,并且两条路不相交的方案数。

题解:只能向右或者向下走,那么起始点肯定一个向左一个向右,结束点肯定一个从上方过来,一个从左方过来,那么题就成了两个点(1,2)(2,1)到两个点(n-1,m)(n,m-1)。就能写了。

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define met(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define bep(i, a, b) for(int i = a; i >= b; i--)
#define re return 0
using namespace std;
const ll mod = 1e9 + 7;
const double PI = acos(-1);
const ll INF = 2e18+1;
const int inf = 1e9 + 15;
const double eps = 1e-7;
const int maxn = 1e6 + 5;
ll d[3003][3003], p[3003][3003];
string ma[3003];
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n, m; cin >> n >> m;
n--, m--;
rep(i, 0, n) cin >> ma[i];
d[0][0] = p[0][0] = 1;
rep(i, 0, n){
rep(j, 1, m){
if(ma[i][j] == '.'){
if(i) d[i][j] += d[i-1][j];
if(j) d[i][j] += d[i][j-1];
d[i][j] %= mod;
}
}
}
rep(i, 1, n){
rep(j, 0, m){
if(ma[i][j] == '.'){
if(i) p[i][j] += p[i-1][j];
if(j) p[i][j] += p[i][j-1];
p[i][j] %= mod;
}
}
}
cout << ((d[n-1][m]*p[n][m-1])%mod - (d[n][m-1]*p[n-1][m])%mod + mod) % mod << endl;
re;
}

牛客多校的题Monotonic Matrix (链接https://vjudge.net/problem/Gym-247727A)

题意:n*m的格子,每个格子可以填0,1,2,要求保证每行每列都是非递减,求可填充的方案数。

题解:

直接上图

也就是找两条线,一条01分割线,一条12分割线。这样就和LGV有联系了,但是LGV求的是不相交(重合也不行),而这题是可以重合的。如下图

为了能用LGV必须让上图变成不重合的,那么就可以平移一个线,可以把红线的起始点终点向左向上平移一格或者把蓝线的起始点终点向右向下平移一个格

我们平移红线,就变成了:

可以发现其实变成了这样:这种可以用LGV求出来不相交的,就等价于上边含有重合的。如果不太理解可以想一下这种求出来的所有方案的情景,把红色向右下移动一格,不就是含有重合的所有方案数吗。

然后可以直接写了,行列式就是,组合数直接得出每个的方案数 = c[n+m][n]*c[n+m][n] - c[n+m][n-1]*c[n+m][n+1];

code:

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define met(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define bep(i, a, b) for(int i = a; i >= b; i--)
#define pb push_back
#define mp make_pair
#define debug cout << "KKK" << endl
#define ls num*2
#define rs num*2+1
#define re return 0
using namespace std;
const ll mod = 1e9 + 7;
const double PI = acos(-1);
const ll INF = 2e18+1;
const int inf = 1e9 + 15;
const double eps = 1e-7;
const int maxn = 1e6 + 5;
ll c[2005][1111];
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
c[0][0] = 1;
rep(i, 1, 2000){
c[i][0] = 1;
rep(j, 1, min(i, 1005)){
c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod;
}
}
int n, m;
while(cin >> n >> m){
cout << ((c[n+m][n]*c[n+m][n])%mod - (c[n+m][n-1]*c[n+m][n+1])%mod + mod) % mod << endl;
}
re;
}

LGV算法 CodeForces 348D + 牛客多校 A Monotonic Matrix的更多相关文章

  1. 2019牛客多校第一场 I Points Division(动态规划+线段树)

    2019牛客多校第一场 I Points Division(动态规划+线段树) 传送门:https://ac.nowcoder.com/acm/contest/881/I 题意: 给你n个点,每个点有 ...

  2. 牛客多校第一场 B Inergratiion

    牛客多校第一场 B Inergratiion 传送门:https://ac.nowcoder.com/acm/contest/881/B 题意: 给你一个 [求值为多少 题解: 根据线代的知识 我们可 ...

  3. 2019牛客多校第二场 A Eddy Walker(概率推公式)

    2019牛客多校第二场 A Eddy Walker(概率推公式) 传送门:https://ac.nowcoder.com/acm/contest/882/A 题意: 给你一个长度为n的环,标号从0~n ...

  4. 牛客多校第三场 F Planting Trees

    牛客多校第三场 F Planting Trees 题意: 求矩阵内最大值减最小值大于k的最大子矩阵的面积 题解: 矩阵压缩的技巧 因为对于我们有用的信息只有这个矩阵内的最大值和最小值 所以我们可以将一 ...

  5. 牛客多校第三场 G Removing Stones(分治+线段树)

    牛客多校第三场 G Removing Stones(分治+线段树) 题意: 给你n个数,问你有多少个长度不小于2的连续子序列,使得其中最大元素不大于所有元素和的一半 题解: 分治+线段树 线段树维护最 ...

  6. 牛客多校第四场sequence C (线段树+单调栈)

    牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...

  7. 牛客多校第3场 J 思维+树状数组+二分

    牛客多校第3场 J 思维+树状数组+二分 传送门:https://ac.nowcoder.com/acm/contest/883/J 题意: 给你q个询问,和一个队列容量f 询问有两种操作: 0.访问 ...

  8. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  9. 2019年牛客多校第一场B题Integration 数学

    2019年牛客多校第一场B题 Integration 题意 给出一个公式,求值 思路 明显的化简公式题,公式是分母连乘形式,这个时候要想到拆分,那如何拆分母呢,自然是裂项,此时有很多项裂项,我们不妨从 ...

  10. 2020牛客多校第八场K题

    __int128(例题:2020牛客多校第八场K题) 题意: 有n道菜,第i道菜的利润为\(a_i\),且有\(b_i\)盘.你要按照下列要求给顾客上菜. 1.每位顾客至少有一道菜 2.给顾客上菜时, ...

随机推荐

  1. 笔记:vue.nextTick()方法的使用详解

    vue.nextTick定义: 在下次DOM更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的DOM. 简单理解:数据更新了,在dom渲染后立即执行该函数 举例 注意:Vue实 ...

  2. 3月1日Android开学学习

    Android开发的简单控件 1.文本显示 2.视图基础 3.常用布局 4.按钮触控 5.图像显示 文本显示 (1)设置文本内容 1.在XML文件中通过属性Android:text设置文本 Andro ...

  3. Error:fatal: no such path /web/controller/XXXController.java in HEAD. 报错!

    现象: Error:fatal: no such path /test/XXXController.java in HEAD. 报错! 原因: 重命名文件夹大小写问题: 解决办法: git mv Te ...

  4. 二维Svg转矢量 不支持Svg2.0

    import { ElMessage } from 'element-plus' import { parse } from 'svgson' import JsonToView from './vi ...

  5. vue3 技术浏览 收藏

    Vue3教程:Vue3.0 + Vant3.0 搭建种子项目 链接:https://www.cnblogs.com/han-1034683568/p/13875663.html

  6. STM32任意引脚模拟IIC

    关于模拟I2C,任意接口都可模拟(未全部测试,可能存在特殊情况). 关于SDA_IN与SDAOUT:如下定义: 举例:#define MPU_SDA_IN() {GPIOA->CRL&= ...

  7. linux sync命令

    Linux sync命令用于数据同步,sync命令是在关闭Linux系统时使用的. Linux 系统中欲写入硬盘的资料有的时候为了效率起见,会写到 filesystem buffer 中,这个 buf ...

  8. mmdetection RPNHead--_init_()函数

    RPNHead类包含的函数: (1)_init_():初始化函数 (2)_init_layers():设置Head中的卷积层 (3)forward_single():单尺度特征图的前向传播 (4)lo ...

  9. new一个实例的原理及过程

    前提,要明白new出来的实例是什么,包含了哪些内容? 请看一下举例代码↓↓↓↓ function Person(name,age){ this.name = name; this.age = age; ...

  10. 移动服务(f[i] [j] [k],这三个人,位置为a[i],j,k的最小价值)

    移动服务(f[i] [j] [k],这三个人,位置为a[i],j,k的最小价值) 题意 给出点之间到达价值,使用3个人处理一个序列,f[i] [j] [k],这三个人,每次处理序列中一个值,三个人中一 ...