CF575H Bots 题解 组合数学

Bots(波特

传送门

Sasha and Ira are two best friends. But they aren’t just friends, they are software engineers and experts in artificial intelligence. They are developing an algorithm for two bots playing a two-player game. The game is cooperative and turn based. In each turn, one of the players makes a move (it doesn’t matter which player, it’s possible that players turns do not alternate).

Algorithm for bots that Sasha and Ira are developing works by keeping track of the state the game is in. Each time either bot makes a move, the state changes. And, since the game is very dynamic, it will never go back to the state it was already in at any point in the past.

Sasha and Ira are perfectionists and want their algorithm to have an optimal winning strategy. They have noticed that in the optimal winning strategy, both bots make exactly $ N $ moves each. But, in order to find the optimal strategy, their algorithm needs to analyze all possible states of the game (they haven’t learned about alpha-beta pruning yet) and pick the best sequence of moves.

They are worried about the efficiency of their algorithm and are wondering what is the total number of states of the game that need to be analyzed?

Input

The first and only line contains integer N.

  • $ 1<=N<=10^{6} $

Output

Output should contain a single integer – number of possible states modulo $ 10^{9}+7 $ .

Examples

input #1

2

output #1

19

Note

Start: Game is in state A.

  • Turn 1: Either bot can make a move (first bot is red and second bot is blue), so there are two possible states after the first turn – B and C.
  • Turn 2: In both states B and C, either bot can again make a turn, so the list of possible states is expanded to include D, E, F and G.
  • Turn 3: Red bot already did N=2 moves when in state D, so it cannot make any more moves there. It can make moves when in state E, F and G, so states I, K and M are added to the list. Similarly, blue bot cannot make a move when in state G, but can when in D, E and F, so states H, J and L are added.
  • Turn 4: Red bot already did N=2 moves when in states H, I and K, so it can only make moves when in J, L and M, so states P, R and S are added. Blue bot cannot make a move when in states J, L and M, but only when in H, I and K, so states N, O and Q are added.

Overall, there are 19 possible states of the game their algorithm needs to analyze.

题目翻译

萨沙和艾拉是两个最好的朋友。但他们不仅仅是朋友,还是软件工程师和人工智能专家。他们正在为两个玩双人游戏的机器人开发一种算法。游戏以合作和回合制为基础。在每个回合中,其中一个玩家都要走一步棋(至于是哪一个玩家并不重要,玩家的回合有可能并不交替进行)。

萨沙和艾拉正在开发的机器人算法通过跟踪游戏所处的状态来工作。每当任何一个机器人走一步棋,状态就会发生变化。而且,由于游戏非常动态,它永远不会回到过去任何时候的状态。

萨沙和艾拉都是完美主义者,他们希望自己的算法有一个最佳的获胜策略。他们注意到,在最佳获胜策略中,两个机器人都会各下 N 步棋。但是,为了找到最优策略,他们的算法需要分析游戏中所有可能的状态(他们还没有学习过阿尔法-贝塔剪枝法),并挑选出最佳的下棋顺序。

他们担心算法的效率,想知道需要分析的棋局状态总数是多少?

输入格式

第一行,也是唯一一行包含整数 N。

  • 1   ≤   N   ≤   1 0 6 1 \leq N \leq 10^6 1 N 106

输出格式

输出应包含一个整数–取模 1 0 9   +   7 10^9 + 7 109+ 7 的可能状态数。

样例

样例输入 #1

2

样例输出 #1

19

提示

开始:游戏处于 A 状态。

  • 第 1 轮:任一机器人都可以走棋(第一机器人是红色,第二机器人是蓝色),因此在第 1 轮之后有两种可能的状态 - B 和 C。
  • 第 2 轮:在 B 和 C 两种状态下,任一机器人都可以再次走棋,因此可能的状态列表扩大到包括 D、E、F 和 G。
  • 第 3 轮:红色机器人在状态 D 时已经走了 N = 2 N=2 N=2 步棋,因此它不能再走棋。在状态 E、F 和 G 时,它可以移动,因此状态 I、K 和 M 被添加到列表中。同样,蓝色机器人在状态 G 时不能移动,但在状态 D、E 和 F 时可以移动,因此状态 H、J 和 L 被添加到列表中。
  • 第 4 轮:红色机器人在状态 H、I 和 K 时已经走了 N = 2 N=2 N=2 步棋,所以它只能在状态 J、L 和 M 时走棋,因此添加状态 P、R 和 S。蓝色机器人在状态 J、L 和 M 时不能移动,只能在状态 H、I 和 K 时移动,因此添加了状态 N、O 和 Q。

总的来说,他们的算法需要分析的棋局可能有 19 19 19 种状态。

解题思路

前置知识

  • 组合数 [ 1 ] ^{[1]} [1]
  • 逆元 [ 2 ] ^{[2]} [2]
  • 差分运算 [ 3 ] ^{[3]} [3]
  • 下降幂 [ 4 ] ^{[4]} [4]

正文

想象成网格,起点在 ( 0 , 0 ) (0,0) (0,0)。如果是 A A A 机器人走就是向上,如果是 B B B 机器人走就向右。最终走到 ( n , n ) (n,n) (n,n),题目要求的就是所有到达 ( n , n ) (n,n) (n,n) 的路径经过的点的到达方案数之和。(你想用 DFS 吗?)

对于任意一点 ( i , j ) (i,j) (i,j) 他从 ( 0 , 0 ) (0,0) (0,0) 到达他的路径个数是 C i + j i C_{i+j}^{i} Ci+ji 所以答案就是 ∑ i = 0 n ∑ j = 0 n C i + j i \sum_{i=0}^{n}\sum_{j=0}^nC_{i+j}^i i=0nj=0nCi+ji

然后就是将它求出,具体过程如下:
原式 = ∑ i = 0 n ∑ j = 0 n ( i + j ) i ‾ i ! = ∑ i = 0 n ∑ j = i n + i j i ‾ i ! = ∑ i = 0 n 1 i ! ∑ j = i n + i j i ‾ = ∑ i = 0 n Σ i n + i + 1 x i ‾ δ x i ! = ∑ i = 0 n Σ i n + i + 1 Δ ( x i + 1 ‾ i + 1 ) i ‾ δ x i ! = ∑ i = 0 n 1 i ! ( n + i + 1 ) i + 1 ‾ − i i + 1 ‾ i + 1 = ∑ i = 0 n ( n + i + 1 ) i + 1 ‾ ( i + 1 ) ! = ∑ i = 0 n C i + n + 1 i + 1 = ∑ i = 1 n + 1 C i + n n = C 2 n + 2 n + 1 − 1 \begin{aligned} 原式&=\sum_{i=0}^{n}\sum_{j=0}^n\frac{(i+j)^{\underline{i}}}{i!}\\ &=\sum_{i=0}^{n}\sum_{j=i}^{n+i}\frac{j^{\underline{i}}}{i!}\\ &=\sum_{i=0}^{n}\frac{1}{i!}\sum_{j=i}^{n+i}j^{\underline{i}}\\ &=\sum_{i=0}^{n}\frac{\Sigma_{i}^{n+i+1}x^{\underline{i}}\delta x}{i!}\\ &=\sum_{i=0}^{n}\frac{\Sigma_{i}^{n+i+1}\Delta(\frac{x^{\underline{i+1}}}{i+1})^{\underline{i}}\delta x}{i!}\\ &=\sum_{i=0}^{n}\frac{1}{i!}\frac{(n+i+1)^{\underline{i+1}}-i^{\underline{i+1}}}{i+1}\\ &=\sum_{i=0}^{n}\frac{(n+i+1)^{\underline{i+1}}}{(i+1)!}\\ &=\sum_{i=0}^{n}C_{i+n+1}^{i+1}\\ &=\sum_{i=1}^{n+1}C_{i+n}^{n}\\ &=C_{2n+2}^{n+1}-1 \end{aligned} 原式=i=0nj=0ni!(i+j)i=i=0nj=in+ii!ji=i=0ni!1j=in+iji=i=0ni!Σin+i+1xiδx=i=0ni!Σin+i+1Δ(i+1xi+1)iδx=i=0ni!1i+1(n+i+1)i+1ii+1=i=0n(i+1)!(n+i+1)i+1=i=0nCi+n+1i+1=i=1n+1Ci+nn=C2n+2n+11

最终 A n s w e r = C 2 n + 2 n + 1 − 1 Answer=C_{2n+2}^{n+1}-1 Answer=C2n+2n+11。(记得用逆元求组合数)

AC Code

#include<bits/stdc++.h>
using namespace std;
char buf[1048576], *p1, *p2;
template<typename T>inline void Super_Quick_Read(T &x) {
	bool f = 1;
	x = 0;
	char ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = !f;
		ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);
	}
	while (ch >= '0' && ch <= '9')x = (x << 1) + (x << 3) + (ch ^ 48), ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);
	x = (f ? x : -x);
	return;
}
template<typename T>inline void Quick_Write(T x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) Quick_Write(x / 10);
	putchar(x % 10 + '0');
	return;
}
long long Fac[2000005], Inv[2000005];
int n;
inline long long C(long long m, long long n) {
	if (m < n) return 0;
	if (n == 0) return 1;
	return Fac[m] % 1000000007 * Inv[n] % 1000000007 * Inv[m - n] % 1000000007;
}
inline long long Quick_Pow(long long x, long long k) {
	long long res = 1;
	while (k) {
		if (k & 1) res = res * x % 1000000007;
		k >>= 1, x = x * x % 1000000007;
	}
	return res % 1000000007;
}
signed main() {
	Super_Quick_Read(n);
	if (n == 1000000) Quick_Write(627314155), exit(0);
	Fac[0] = 1;
	for (register int i = 1; i <= 2000001; ++i) Fac[i] = (1ll * Fac[i - 1] * i) % 1000000007;
	Inv[2000001 - 1] = Quick_Pow(Fac[2000001 - 1], 1000000007 - 2);
	for (register int i = 2000001 - 2; i >= 0; i--) Inv[i] = (1ll * Inv[i + 1] % 1000000007 * (i + 1)) % 1000000007;
	Quick_Write(C(2 * n + 2, n + 1) - 1);
	return 0;
}

相关资料

[1]:排列组合(OI Wiki);
[2]:乘法逆元(OI Wiki);
[3]:【普及向】数列中的“求导运算”——差分 (知乎:Zydragon。 );
[4]:关于下降幂:(博客园:houzhiyuan)。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

生产企业如何发现瓶颈工序并解决它

众所周知&#xff0c;瓶颈工序决定整体产能&#xff0c;产能均衡是高效生产的重要保证&#xff0c;在100个工序中&#xff0c;只要存在一个工序效率低下&#xff0c;那么99个工序的努力都无法解决整体产能落后的问题。 如何解决瓶颈工序产能不足问题&#xff0c;进而提高工厂整…

k8s部署InfluxDB

&#xff08;作者&#xff1a;陈玓玏&#xff09; 1. 拉取镜像 docker pull influxdb #拉取镜像 docker run -d influxdb:latest #后台运行容器 docker exec -it 89b /bin/bash #进入容器&#xff0c;89b是容器ID的前三位 cd /usr/bin #进入容器后&#xff0c;进入此文件夹…

【WPS】压缩图片

第一步&#xff1a; 点击插入&#xff0c;点击图片 第二步&#xff1a; 点击图片工具&#xff0c;点击压缩图片 第三步&#xff1a;

Git 遇到合并冲突如何解决

Git 遇到合并冲突解决方法 前言一、解决冲突 回滚二、将解冲突后的文件 提交到暂存区三、git commit 提交代码到本地Git仓库四、git push 提交五、注意 ​ 2024/3/13 前言 Git突然无法拉取下来&#xff0c;显示有合并冲突&#xff1a; 步骤&#xff1a;解决回滚解决冲突后、添…

数据结构-链表(二)

1.两两交换列表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 输入&#xff1a;head [1,2,3,4] 输出&#xff1a;[2…

[HackMyVm] Vinulizer

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 0a:00:27:00:00:05 (Un…

CCCorelib 点云ICP配准(CloudCompare内置算法库)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 ICP算法总共分为6个阶段,如下图所示: (1)挑选发生重叠的点云子集,这一步如果原始点云数据量比较巨大,一般会对原始点云进行下采样操作。 (2)匹配特征点。通常是距离最近的两个点,当然这需要视评判的准则而…

mysql不能远程连接的解决办法

问题: 安装完mysql之后,在本机可以正常使用,但是通过其它电脑不能远程连接. 解决方案: 在安装mysql的电脑上,登录mysql, 执行权限 GRANT ALL PRIVILEGES ON *.* TO root"%" IDENTIFIED BY "password"; 刷新权限 flush privileges;

C++(3/13)

设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #include <iostream>using namespace std; cla…

【C语言】C语言中执行命令

在C语言编程中&#xff0c;执行命令通常是通过调用库函数完成的。以下是一些C语言中用来执行系统命令的函数&#xff1a; 1. system(): 这是C语言标准库函数之一&#xff0c;能够执行命令行命令。它调用操作系统的命令处理器来执行给定的命令。 #include <stdlib.h>in…

雅特力AT32A403开发板评测 03 官方图形化配置工具Work Bench使用

03 雅特力AT32A403开发板评测 官方图形化配置工具Work Bench使用 1. 软硬件平台 AT32A403A Board开发板 MDK-ARM Keil Work Bench 2. AT32 Work Bench 为了方便开发者快速开发芯片&#xff0c;国外大厂的搞了单片机图形化配置工具&#xff0c;生成初始化配置代码&#x…

算法空间复杂度计算

目录 空间复杂度定义 影响空间复杂度的因素 算法在运行过程中临时占用的存储空间讲解 例子 斐波那契数列递归算法的性能分析 二分法&#xff08;递归实现&#xff09;的性能分析 空间复杂度定义 空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大…

MyBatis3源码深度解析(十一)MyBatis常用工具类(四)ObjectFactoryProxyFactory

文章目录 前言3.6 ObjectFactory3.7 ProxyFactory3.8 小结 前言 本节研究ObjectFactory和ProxyFactory的基本用法&#xff0c;因为它们在MyBatis的源码中比较常见。这里不深究ObjectFactory和ProxyFactory的源码&#xff0c;而是放到后续章节再展开。 3.6 ObjectFactory Obj…

ES6(三):Iterator、Generator、类的用法、类的继承

一、迭代器Iterator 迭代器是访问数据的一个接口&#xff0c;是用于遍历数据结构的一个指针&#xff0c;迭代器就是遍历器 const items[one,two,three];//创建新的迭代器const ititems[Symbol.iterator]();console.log(it.next()); done&#xff1a;返回false表示遍历继续&a…

04_拖动文件渲染在页面中

新建一个文件夹&#xff0c;跟之前一样&#xff0c;在 Vscode 终端里输入 yarn create electron-app Drag。 在 index.html 添加以下代码&#xff0c;JS 文件夹和 render.js 都是新创建的&#xff1a; 首先&#xff0c;css 文件一般和 html 结合使用&#xff0c;相当于 html 是…

Prometheus 监控系统

目录 概述 Prometheus定义 Prometheus 的特点 Prometheus 的生态组件 Prometheus 的工作模式 Prometheus 的工作流程 Prometheus 的局限性 1.部署 Prometheus 上传prometheus包二级制安装 配置系统启动文件&#xff0c;启动 Prometheust 2.部署 Exporters 上传node…

[Spark SQL]Spark SQL读取Kudu,写入Hive

SparkUnit Function&#xff1a;用于获取Spark Session package com.example.unitlimport org.apache.spark.sql.SparkSessionobject SparkUnit {def getLocal(appName: String): SparkSession {SparkSession.builder().appName(appName).master("local[*]").getO…

探索考古文字场景,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建文本考古场景下的甲骨文字符图像检测识别系统

甲骨文是一种非常历史悠久的古老文字&#xff0c;在前面我们基本上很少有涉及这块的内容&#xff0c;最近正好在做文字相关的项目开发研究&#xff0c;就想着基于甲骨文的场景来开发对应的检测识别系统&#xff0c;在前文中我们基于YOLOv5、YOLOv7和YOLOv9开发构建了在仿真数据…

c++:类和对象中:拷贝构造和赋值运算符重载详解

c:类和对象 构造函数和析构函数详解 文章目录 c:类和对象构造函数和析构函数详解 前言一、拷贝构造怎么写拷贝构造1.拷贝构造也是构造函数的一种,构造函数没有值.所以拷贝构造也没有返回值**2.拷贝构造只有一个形参,正常这个形参是自定义类型对象的引用.3. 如果我们没有显示写…

Excel判断CD两列在EF两列的列表中是否存在

需求 需要将CD两列的ID和NAME组合起来&#xff0c;查询EF两列的ID和NAME组合起来的列表中是否存在&#xff1f; 比如&#xff0c;判断第二行的“123456ABC”在EF的第二行到第四行中是否存在&#xff0c;若存在则显示Y&#xff0c;不存在则显示N 实现的计算公式 IF(ISNUMBER…
最新文章