51 nod 1486 大大走格子 容斥原理+组合数学+dp

2023-12-07 03:58

本文主要是介绍51 nod 1486 大大走格子 容斥原理+组合数学+dp,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1486 大大走格子
题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
有一个h行w列的棋盘,里面有一些格子是不能走的,每次只能往下、往右走。现在要求从左上角走到右下角的方案数。
Input
单组测试数据。
第一行有三个整数h, w, n(1 ≤ h, w ≤ 10^5, 1 ≤ n ≤ 2000),表示棋盘的行和列,还有不能走的格子的数目。
接下来n行描述格子,第i行有两个整数ri, ci (1 ≤ ri ≤ h, 1 ≤ ci ≤ w),表示格子所在的行和列。
输入保证起点和终点不会有不能走的格子。
Output
输出答案对1000000007取余的结果。
Input示例
3 4 2
2 2
2 3

Output示例

2

题解:很容易想到这是一道dp的题,很容易写出方程dp【i】【j】=dp【i-1】【j】+dp【i】【j-1】。这可是杨辉三角一般的方程啊,好啦,结论出来啦,从左上走到右下直接=C(m+n-2,m-1)。但这道题有一些格子不能走,那么补集思想就来啦,用总方案数-经过非法格点的方案数=合法方案数。非法格点方案数=(经过一个非法格点方案数-进过两个非法格点方案数+经过三个非法格点方案数……)(容斥原理:奇加偶减),现在难点就在怎么求经过i个非法格点方案数。通过之前的dp已经求出左上到任意格点的距离,包括非法格点,那么可以通过非法格点之间的来找。先将非法格点按x,y坐标排序,目的是枚举走到非法格点i可以经过的其他非法格点,找出两个非法格i,j(i 在j之后)点之间的路径条数num,则这num条路径就不合法,f【i】表示走大非法节点i不经过其他非法节点的数量,f【i】=f【i】-f【j】*num,因为是层层往后推的,所以讲(n,m)也视为非法节点,则答案为dp【(n,m)】。为什么这是容斥原理呢,可以证明:f【i】-f【j】*num,其中可以把f【j】拆成f【j】-f【k】*num~,因为是减法,所以最终推到终点的时候满足奇加偶减。

总结:容斥原理可以是明显的,也可以是不明显的,比如本题就不太明显,以后要一个阶段一个阶段的分析,找出阶段之间的重复部分,合理容斥。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#define N 2100000
#define x1 (point[i].x)
#define y1 (point[i].y)
#define x2 (point[j].x)
#define y2 (point[j].y)
#define calc(m,n) (re[m]*inv[n]%mod*inv[m-n]%mod)%mod
#define rdx(i) point[i].x=read()
#define rdy(i) point[i].y=read()
using namespace std;
int n,m,k;
long long dp[N],inv[N],re[N];
long long mod=1e9+7;
inline int read()
{int ra,fh;char rx;rx=getchar(),ra=0,fh=1;while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();if(rx=='-')fh=-1,rx=getchar();while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
}
struct node
{int x,y;
}point[N];
bool cmp(node a,node b){return a.x==b.x?a.y<b.y:a.x<b.x;
}
long long get_inv(long long x)
{long long ans=1;long long y=mod-2;while(y){if(y&1) ans=ans*x%mod;x=x*x%mod;y>>=1;}return ans;
}
void init()
{re[0]=1;int tm=m+n-2;for(int i=1;i<=tm;i++)re[i]=re[i-1]*i%mod;inv[tm]=get_inv(re[tm]);for(int i=tm-1;i>=0;i--)inv[i]=inv[i+1]*(i+1)%mod;return ;
}
int main()
{n=read();m=read();k=read();for(int i=1;i<=k;i++) rdx(i),rdy(i);sort(point+1,point+1+k,cmp);point[++k].x=n;point[k].y=m;init();for(int i=1;i<=k;i++){ 	int a=point[i].x+point[i].y-2,b=point[i].x-1;dp[i]=calc(a,b)%mod;for(int j=1;j<i;j++)if(x1>=x2 && y1>=y2){int ce=(x1-x2+y1-y2);int xe=(x1-x2);dp[i]=(dp[i]-dp[j]*calc(ce,xe)%mod+mod)%mod;		} 	}printf("%lld\n",dp[k]);return 0;
}

这篇关于51 nod 1486 大大走格子 容斥原理+组合数学+dp的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/464404

相关文章

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操

kotlin中的模块化结构组件及工作原理

《kotlin中的模块化结构组件及工作原理》本文介绍了Kotlin中模块化结构组件,包括ViewModel、LiveData、Room和Navigation的工作原理和基础使用,本文通过实例代码给大家... 目录ViewModel 工作原理LiveData 工作原理Room 工作原理Navigation 工

Java的volatile和sychronized底层实现原理解析

《Java的volatile和sychronized底层实现原理解析》文章详细介绍了Java中的synchronized和volatile关键字的底层实现原理,包括字节码层面、JVM层面的实现细节,以... 目录1. 概览2. Synchronized2.1 字节码层面2.2 JVM层面2.2.1 ente

MySQL的隐式锁(Implicit Lock)原理实现

《MySQL的隐式锁(ImplicitLock)原理实现》MySQL的InnoDB存储引擎中隐式锁是一种自动管理的锁,用于保证事务在行级别操作时的数据一致性和安全性,本文主要介绍了MySQL的隐式锁... 目录1. 背景:什么是隐式锁?2. 隐式锁的工作原理3. 隐式锁的类型4. 隐式锁的实现与源代码分析4

MySQL中Next-Key Lock底层原理实现

《MySQL中Next-KeyLock底层原理实现》Next-KeyLock是MySQLInnoDB存储引擎中的一种锁机制,结合记录锁和间隙锁,用于高效并发控制并避免幻读,本文主要介绍了MySQL中... 目录一、Next-Key Lock 的定义与作用二、底层原理三、源代码解析四、总结Next-Key L