Codeforces 559C 详细题解

文章目录

      • 1. 题意
      • 2. 题解
        • 2.1 情况0:如果不存在障碍物
        • 2.2 情况1: 如果存在一个障碍物
        • 3.3 情况2:如果存在两个障碍物
        • 3.4 情况3: 如果存在多个障碍物
      • 4. 代码实现
      • 5. 从集合角度看
      • 6. 参考

1. 题意

  给定 h × w h\times w h×w大小的二维数组, 再给定 n n n个障碍

物。我们从左上角出发,每次只能向右或者向下走

动,问有多少种方法从左上到右下?

cf559c

2. 题解

动态规划+组合计数+容斥原理+乘法逆元

我们一步步慢慢分析

2.1 情况0:如果不存在障碍物

  首先我们分析,如果没有障碍物,

( 0 , 0 ) (0,0) (0,0) ( x , y ) (x,y) (x,y)一共有多少种走法呢?没错应该是

( x + y x ) {x+y \choose x} (xx+y)种。为什么呢?我们一共要走

x + y x+y x+y步, x x x步向下, y y y步向右,因此也就是 x + y x+y x+y

步中选择 x x x步向下,或者 y y y步向下, 也就是

a n s = ( x + y x ) = ( x + y y ) ans ={x+y \choose x}={x+y \choose y} ans=(xx+y)=(yx+y)

2.2 情况1: 如果存在一个障碍物

  如果在 ( 0 , 0 ) (0,0) (0,0) ( x , y ) (x,y) (x,y)之间存在一个障碍物

( x 0 , y 0 ) (x_0,y_0) (x0,y0), 我们可以直接用总数减去通过该障碍物的

路径数目。经过障碍物到达右下的路径数可以通过

乘法计数来求得

( x 0 + y 0 x 0 ) ( x + y − x 0 − y 0 x − x 0 ) {x_0+y_0 \choose x_0}{x+y-x_0-y_0 \choose x-x_0} (x0x0+y0)(xx0x+yx0y0)

因此最终的路径数目为
a n s = ( x + y x ) − ( x 0 + y 0 x 0 ) ( x + y − x 0 − y 0 x − x 0 ) ans={x+y \choose x}-\\{x_0+y_0 \choose x_0}{x+y-x_0-y_0 \choose x-x_0} ans=(xx+y)(x0x0+y0)(xx0x+yx0y0)

3.3 情况2:如果存在两个障碍物

  假设这两个障碍物位置为

B 0 ( x 0 , y 0 ) , B 1 ( x 1 , y 1 ) B_0(x_0, y_0), B_1(x_1, y_1) B0(x0,y0),B1(x1,y1)

  我们需要分情况进行讨论,这两个障碍物是否

独立。所谓独立就是说,在经过 B 0 B_0 B0去往右下角终点

的路径上是否会出现点 B 1 B_1 B1; 如果出现了,那么在计

数的时候就会出现重复,需要去除重复的路径数。

我们容易得到,如果两者之间只要满足

( x 0 − x 1 ) ( y 0 − y 1 ) < 0 (x_0-x_1)(y_0-y_1) < 0 (x0x1)(y0y1)<0, 它们两点之间就独立。

  对于独立的点,我们逐个减去经过它到达终点

的方案数就可以了。

a n s = ( x + y x ) − ∑ i = 0 1 ( x i + y i x i ) ( x − x i + y − y i x − x i ) ans= {x+y \choose x} -\\\sum_{i=0}^1{x_i+y_i \choose x_i} { x-x_i+y-y_i \choose x-x_i} ans=(xx+y)i=01(xixi+yi)(xxixxi+yyi)


  而对于两点不独立存在重复的情况,我们要试

着让他们独立。

  假设 B 1 在 B 0 B_1在B_0 B1B0的右下,也就是 x 0 < = x 1 ∧ y 0 < = y 1 x_0 <= x_1 \land y_0 <= y_1 x0<=x1y0<=y1

  我们在计算经过 B 0 B_0 B0到达右下角的路径中必然包

含了同时经过 B 0 B 1 B_0B_1 B0B1到达右下角的路径,因此我们

只需要计算经过 B 1 B_1 B1而经过 B 0 B_0 B0到达右下角的路径数

目。也就是到达 B 1 B_1 B1的路径上不能有其他障碍物,而

从左上角不经过障碍物到 B 1 B_1 B1的方案数实际上就是求

情况1

我们定义 d p [ i ] [ j ] dp[i][j] dp[i][j]为不经过障碍物从 ( 0 , 0 ) (0, 0) (0,0)到达

( i , j ) (i,j) (i,j)的可能路径数。最终的路径数为:

a n s = d p [ x ] [ y ] = ( x + y x ) − ∑ i = 0 1 d p [ x i ] [ y i ] ( x + y − x i − y i x − x i ) ans = dp[x][y]= {x+y \choose x}-\\\sum_{i=0}^1dp[x_i][y_i]{x+y-x_i -y_i \choose x-x_i} ans=dp[x][y]=(xx+y)i=01dp[xi][yi](xxix+yxiyi)

3.4 情况3: 如果存在多个障碍物

  多个障碍物独立的情况仍然是直接减就可以了
a n s = d p [ x ] [ y ] = ( x + y x ) − ∑ i = 0 k ( x i + y i x i ) ( x − x i + y − y i x − x i ) ans=dp[x][y]={x+y \choose x} -\\\sum_{i=0}^k{x_i+y_i \choose x_i} { x-x_i+y-y_i \choose x-x_i} ans=dp[x][y]=(xx+y)i=0k(xixi+yi)(xxixxi+yyi)
  如果这 k k k个点都不独立,我们需要从左

上的点开始算,因为它会包含经过后面障碍的路

径。依次将它们独立,也就是依次求出 d p [ x i ] [ y i ] dp[x_i][y_i] dp[xi][yi]

再像处理情况2那样处理最终的路径数

a n s = d p [ x ] [ y ] = ( x + y x ) − ∑ i = 0 k d p [ x i ] [ y i ] ( x + y − x i − y i x − x i ) ans=dp[x][y]= {x+y \choose x}-\\\sum_{i=0}^kdp[x_i][y_i]{x+y-x_i -y_i \choose x-x_i} ans=dp[x][y]=(xx+y)i=0kdp[xi][yi](xxix+yxiyi)

4. 代码实现

  我们将右下角坐标也放入障碍物数组,再

将障碍物按左上右下的顺序进行排序;依次求

d p [ x i ] [ y i ] dp[x_i][y_i] dp[xi][yi]即可;组合数较大需要取模,预处理乘

法逆元就可以了, 可以用费马小+快速幂或者是扩展

欧几里得求出最大的阶乘逆元,再线性递推求出其

他阶乘的逆元。

#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>using ll = long long;static constexpr int MAXN = 200005;ll fac[MAXN + 1];
ll ifac[MAXN + 1];
ll MOD = 1e9 + 7;ll exgcd(ll a, ll b, ll &x, ll &y) {if (0 == b) {x = 1;y = 0;return a;}ll d = exgcd( b, a % b, y, x);y -= (a / b) * x;return d;
}
ll fpow(ll base, ll cnt) {ll ans = 1;ll tmp = base;while (cnt) {if (cnt & 1) ans = ans * tmp % MOD;tmp = tmp * tmp % MOD;cnt >>= 1;}return ans;
}void init () {fac[0] = ifac[0] = 1;fac[1] = 1;ifac[1] = 1;for (int i = 2; i <= MAXN; i++) {fac[i] = fac[i - 1] * i % MOD; }//ll y;//exgcd( fac[MAXN], MOD, ifac[MAXN], y);ifac[MAXN] = fpow(fac[MAXN], MOD - 2);for (int i = MAXN - 1; i > 1; i--) {ifac[i] = ifac[i + 1] * (i + 1) % MOD;}}
ll Comb(int n, int k) {if (n == k || k == 0) {return 1;}return fac[n] * ifac[k] % MOD * ifac[n - k] % MOD;
}
int main()
{init();int h;int w;int n;std::cin >> h >> w >> n;std::vector<std::pair<int, int> > b;for (int i = 0;i < n;i++) {int x;int y;std::cin >> x >> y;b.push_back(std::make_pair<>(x, y));}std::sort(b.begin(), b.end(),[](const std::pair<int,int> &f, const std::pair<int,int> &s){return f.first == s.first ? f.second < s.second : f.first < s.first;});b.push_back(std::make_pair( h, w));std::vector<ll> dp( n + 1, 0);for (int i = 0;i < n + 1; ++i) {int r = b[i].first;int c = b[i].second;ll res = Comb(r + c - 2, r - 1);for (int j = 0;j < i;++j) {int rr = b[j].first;int cc = b[j].second;if (rr <= r && cc <= c) {res = res + MOD -  (dp[j] * Comb(r + c - rr - cc, r - rr) % MOD) ;res = res % MOD ;}}dp[i] = res;}std::cout << dp[n] << std::endl;return 0;
}

5. 从集合角度看

假设共有 n n n个障碍物分别为 B 0 ( x 0 , y 0 ) ⋯ B n − 1 ( x n − 1 , y n − 1 ) B_0(x_0,y_0)\cdots B_{n-1}(x_{n-1},y_{n-1}) B0(x0,y0)Bn1(xn1,yn1)

且当 i < j , x i ≤ x j ∧ y i ≤ y j i <j, x_{i} \le x_{j} \land y_i \le y_j i<j,xixjyiyj

也就是上面说得排好序,经过 B i B_i Bi到达终点的路径

包含同时经过 B i B j B_i\ B_j Bi Bj的路径。

我们令事件 P i , 0 ≤ 0 < n P_i, 0 \le 0 <n Pi,00<n为经过 P i P_i Pi到达终点的路

径。

d p [ i ] dp[i] dp[i]为从 ( 0 , 0 ) (0,0) (0,0)不经过障碍物到达 B i B_i Bi的路径

数。

那么实际上 d p [ i ] dp[i] dp[i]

d p [ i ] = C n t ( P 0 ⋯ P i − 1 ‾ P i ) dp[i] =Cnt(\overline{P_0 \cdots P_{i-1}}P_i) dp[i]=Cnt(P0Pi1Pi)

求出所有不经过障碍物到达右下的路径相当于:

P 0 P 1 ⋯ P n − 1 ‾ = 1 − ( P 0 + P 0 ‾ P 1 + ⋯ P 0 P 1 ⋯ P n − 2 ‾ P n − 1 ) \overline{P_0P_1\cdots P_{n-1}}=1 -(P_0+ \overline{P_0}P_1+\\\cdots \overline{P_0P_1\cdots P_{n-2}}P_{n-1}) P0P1Pn1=1(P0+P0P1+P0P1Pn2Pn1)

6. 参考

03xf-sarinee

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/22553.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三格电子上新了——PLC 数据采集网关

型号&#xff1a;SG-PLC-Private 第一章 产品概述 PLC 转 Modbus 网关型号 SG-PLC-Private &#xff08; PLC 私有协议网关&#xff09;&#xff0c;是三格电子推出的工业 级网关&#xff08;以下简称网关&#xff09;&#xff0c;主要用于 在不需要对 PLC 编程的情况…

算法日记25:01背包(DFS->记忆化搜索->倒叙DP->顺序DP->空间优化)

对于01背包这类DP入门的问题&#xff0c;新手应该是去了解如何一步步得出所谓的状态转移方程&#xff0c;而不是直接去看答案所给予的方程过程应该为&#xff1a;DFS->记忆化搜索->倒序递推->循序递推->二维->一维 一、DFS暴力搜索 O ( 2 n ) O(2^n) O(2n) 1…

Spring AutoWired与Resource区别?

大家好&#xff0c;我是锋哥。今天分享关于【Spring AutoWired与Resource区别?】面试题。希望对大家有帮助&#xff1b; Spring AutoWired与Resource区别? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Spring 中&#xff0c;Autowired 和 Resource 都是用于…

【知识】深度学习中,应该先zero_grad还是先backward?

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 抛出问题 各大GPT的回答 ChatGPT-4o ChatGPT-o3-mini-high Kimi-长思考 Deepseek-R1 Grok3 Pytorch官方教程中 抛出问题 以下哪种方式是…

Python----数据结构(哈希表:哈希表组成,哈希冲突)

一、哈希表 哈希表(Hash table)是一种常用、重要、高效的数据结构。 哈希表通过哈希函数,可以快速地将键(Key)映射到值(Value)。从而允许在近常数时间内对键关联的值进行插入、删除和查找操作。 哈希表的主要思想是通过哈希函数将键转换为索引&#xff0c;将索引映射到数组中…

使用excel中的VBA合并多个excel文件

需求是这样的&#xff1a; 在Windows下&#xff0c;用excel文件让多个小组填写了统计信息&#xff0c;现在我需要把收集的多个文件汇总到一个文件中&#xff0c;前三行为标题可以忽略&#xff0c;第四行为收集信息的列名&#xff0c;处理每一行数据的时候&#xff0c;发现某一行…

功能全面的手机壁纸应用,种类齐全、众多高清壁纸

软件介绍 应用亮点&#xff1a;今天给大家分享一款超神奇的手机应用 —— 奇幻壁纸。它作为手机动态壁纸软件&#xff0c;功能超全面&#xff0c;操作还便捷&#xff0c;极具创意&#xff0c;能瞬间将你的手机屏幕变成奇幻世界&#xff0c;带来全新视觉感受。 使用便捷性&…

docker安装kafka,并通过springboot快速集成kafka

目录 一、docker安装和配置Kafka 1.拉取 Zookeeper 的 Docker 镜像 2.运行 Zookeeper 容器 3.拉取 Kafka 的 Docker 镜像 4.运行 Kafka 容器 5.下载 Kafdrop 6.运行 Kafdrop 7.如果docker pull wurstmeister/zookeeper或docker pull wurstmeister/kafka下载很慢&#x…

前端导出word文件,并包含导出Echarts图表等

基础导出模板 const html <html><head><style>body {font-family: Times New Roman;}h1 {text-align: center;}table {border-collapse: collapse;width: 100%;color: #1118FF;font-weight: 600;}th,td {border: 1px solid black;padding: 8px;text-align: …

2024系统编程语言风云变幻:Rust持续领跑,Zig与Ada异军突起

2024年系统编程语言调查报告新鲜出炉&#xff01;这份报告对Rust、Zig、Ada、C、C等主流语言进行了全面评估&#xff0c;结果令人瞩目。Rust凭借其强大的类型系统和内存安全机制继续领跑&#xff0c;而Zig和Ada则展现出巨大的潜力&#xff0c;为系统编程领域带来了新的活力。本…

Jenkins 构建 Unity 打包 .apk 同时生成 .aab

Jenkins 构建 Unity 打包 .apk 同时生成 .aab Android App Bundle简称 AAB&#xff0c;想了解更多关于 AAB 的知识&#xff0c;请看官网 https://developer.android.google.cn/guide/app-bundle/faq?hlzh-cn APK 打包部分在复用上一篇 Jenkins 构建 Unity打包APK 一、新建一…

JAVAweb-标签选择器,盒模型,定位,浮动

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>标签</title><style type"text/css&q…

计算机视觉:主流数据集整理

第一章&#xff1a;计算机视觉中图像的基础认知 第二章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(一) 第三章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(二) 第四章&#xff1a;搭建一个经典的LeNet5神经网络(附代码) 第五章&#xff1…

二级公共基础之数据结构与算法篇(五)树和二叉树

目录 前言 一、树的基本概念 1.父结点和根节点 2.子节点和叶子节点 3.度和深度 4.子树 二、二叉树及其基本性质 1. 二叉树的定义 2. 二叉树的基本性质 性质1 性质2 性质3 性质4 性质5 性质6 三、二叉树的存储结构 四、二叉树的遍历 1.遍历二叉树的概念 1. 前…

自制操作系统学习第七天

今天要做什么&#xff1f; 实现HLT&#xff0c;不让计算机处于HALT&#xff08;HLT&#xff09;.用C语言实现内存写入&#xff08;错误&#xff0c;需要分析&#xff09; 一:使用HLT&#xff0c;让计算机处于睡眠状态 写了下面这个程序&#xff0c;naskfunc.nas 函数名叫io_h…

Python Django系列—入门实例(二)

数据库配置 现在&#xff0c;打开 mysite/settings.py 。这是个包含了 Django 项目设置的 Python 模块。 默认情况下&#xff0c;​ DATABASES 配置使用 SQLite。如果你是数据库新手&#xff0c;或者只是想尝试 Django&#xff0c;这是最简单的选择。SQLite 包含在 Python 中…

DeepSeek接入Siri(已升级支持苹果手表)完整版硅基流动DeepSeek-R1部署

DeepSeek接入Siri&#xff08;已升级支持苹果手表&#xff09;完整版硅基流动DeepSeek-R1部署 **DeepSeek** 是一款专注于深度学习和人工智能的工具或平台&#xff0c;通常与人工智能、机器学习、自动化分析等领域有关。它的主要功能可能包括&#xff1a;深度学习模型搜索&…

抗辐照加固CAN FD芯片的商业航天与车规级应用解析

在工业自动化、智能汽车、航空航天及国防装备等关键领域&#xff0c;数据传输的安全性、可靠性与极端环境适应能力是技术升级的核心挑战。国科安芯推出全新一代CANFD&#xff08;Controller Area Network Flexible Data Rate&#xff09;芯片&#xff0c;以高安全、高可靠、断电…

Java数据结构第十二期:走进二叉树的奇妙世界(一)

专栏&#xff1a;数据结构(Java版) 个人主页&#xff1a;手握风云 目录 一、树型结构 1.1. 树的定义 1.2. 树的基本概念 1.3. 树的表示形式 二、二叉树 2.1. 概念 2.2. 两种特殊的二叉树 2.3. 二叉树的性质 2.4. 二叉树的存储 三、二叉树的基本操作 一、树型结构 1.…

nginx 反向代理 配置请求路由

nginx | 反向代理 | 配置请求路由 nginx简介 Nginx&#xff08;发音为“Engine-X”&#xff09;是一款高性能、开源的 Web 服务器和反向代理服务器&#xff0c;同时也支持邮件代理和负载均衡等功能。它由俄罗斯程序员伊戈尔西索夫&#xff08;Igor Sysoev&#xff09;于 2004…