可以发现,如果一个整体一起考虑是不能找到一个合适的状态来描述这个情形的。

因此可以考虑寻找整体的反面,也就是将每个维度分开考虑。

不难发现每个维度本质上是一样的,因此不需要考虑不同维度之间的区别。

那么对于每个维度而言,它必须从 \(0\) 出发再回到 \(0\),那么假设它往外走了 \(k\) 步,那么往内也必然走了 \(k\) 步。

不难发现每个维度本质上是在总共的 \(T\) 步中选择了 \(k\) 个位置在这个维度上往外走,再选择 \(k\) 个位置往内走,于是就可以直接考虑 \(dp\) 了。

令 \(dp_{i, j}\) 表示前 \(i\) 个维度一共走了 \(j\) 步的方案,假设最终一共走的步数为 \(T\),那么有转移:

\[dp_{i, j} = \sum\limits_{k = 0} ^ {\lfloor \frac{j}{2} \rfloor} dp_{i - 1, j - 2 \times k} \times \dbinom{T - j + 2 \times k}{k} \times \dbinom{T - j + k}{k}
\]

这样就可以 \(O(n ^ 3)\) 地算了,但每次查询 \(T\) 都会改变,怎么办呢?

回到 \(dp\) 转移之前的这个流程,不难发现实质上本质上是 \(2n\) 个多重集合排列的问题。

回忆一下这个问题:\(m\) 个集合第 \(i\) 个集合内有 \(a_i\) 个元素不标号,满足 \(\sum a_i = n\),问排列的方案数,不难发现即为:

\[\frac{n!}{a_1!a_2! \cdots a_m!}
\]

可以发现分母是与 \(n\) 无关的,而分子又是与每个 \(a_i\) 无关的。

因此我们在 \(dp\) 的过程中先不计算分子对答案的贡献,只计算分母对答案的贡献,最后查询直接乘 \(T!\) 即可。

实际上也可以考虑转移的时候以插入的形式转移,本质上是一致的,在此不再赘述。

#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = l; i <= r; ++i)
const int N = 200 + 5;
const int L = 200;
const int Mod = 1e9 + 7;
int n, T, Q, fac[N], inv[N], dp[N][N];
int read() {
char c; int x = 0, f = 1;
c = getchar();
while (c > '9' || c < '0') { if(c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int Inc(int a, int b) { return (a += b) >= Mod ? a - Mod : a;}
int Dec(int a, int b) { return (a -= b) < 0 ? a + Mod : a;}
int Mul(int a, int b) { return 1ll * a * b % Mod;}
int fpow(int a, int b) { int ans = 1; for (; b; a = Mul(a, a), b >>= 1) if(b & 1) ans = Mul(ans, a); return ans;}
int C(int n, int m) { return n < m ? 0 : Mul(fac[n], Mul(inv[m], inv[n - m]));}
int main() {
fac[0] = inv[0] = dp[0][0] = 1;
rep(i, 1, L) fac[i] = Mul(fac[i - 1], i), inv[i] = fpow(fac[i], Mod - 2);
rep(i, 1, L) rep(j, 0, L) rep(k, 0, j / 2)
dp[i][j] = Inc(dp[i][j], Mul(dp[i - 1][j - 2 * k], Mul(inv[k], inv[k])));
Q = read();
while (Q--) {
n = read(), T = read();
printf("%d\n", Mul(dp[n][T], fac[T]));
}
return 0;
}

值得一提的,广义上的正难则反就是从难点的对立面来考虑,比如:具体问题抽象化,抽象问题具体化,区间问题单点化等等。

SP19149 INS14H - Virus Revisited的更多相关文章

  1. Virus.Win32.Virlock.b分析

    0x00 样本说明 分析样本是被0b500d25f645c0b25532c1e3c9741667的样本感染得到.感染前的文件是Tcpview.exe,一款windows网络连接查看工具. 感染前后文件 ...

  2. csuoj 1394: Virus Replication

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1394 1394: Virus Replication Time Limit: 1 Sec  Mem ...

  3. sublimeText jsformat 插件被当做病毒 virus

    最近在个只可往他里面发邮件,不能往外上任何互联网的地方工作,用 sublimetext 要装个sublime 插件 jsformat 十分麻烦.用gmail邮箱发总是报病毒. 最后挨个尝试,发现是 j ...

  4. hdu 3695:Computer Virus on Planet Pandora(AC自动机,入门题)

    Computer Virus on Planet Pandora Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 256000/1280 ...

  5. HDU 3695 Computer Virus on Planet Pandora(AC自动机模版题)

    Computer Virus on Planet Pandora Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 256000/1280 ...

  6. hdu ----3695 Computer Virus on Planet Pandora (ac自动机)

    Computer Virus on Planet Pandora Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 256000/1280 ...

  7. 最近碰到了一个病毒木马:virus.win32.ramnit.B

    由于 使用了 简单游 平台上的挂机工具: 番茄-自动人机对战免费版1217  ,使用了很久,头段时间家里电脑 360提示有病毒,本来我一直忽略的,但 我扫描了一下,大量的这个木马,于是 吧 简单游卸载 ...

  8. ZOJ 3430 Detect the Virus

    传送门: Detect the Virus                                                                                ...

  9. HDU 3695 / POJ 3987 Computer Virus on Planet Pandora(AC自动机)(2010 Asia Fuzhou Regional Contest)

    Description Aliens on planet Pandora also write computer programs like us. Their programs only consi ...

随机推荐

  1. Improving Adversarial Robustness via Channel-Wise Activation Suppressing

    目录 概 主要内容 代码 Bai Y., Zeng Y., Jiang Y., Xia S., Ma X., Wang Y. Improving adversarial robustness via ...

  2. 单芯片替代PS176 DP转HDMI 4K60HZ DP转HDMI2.0转换芯片CS5263

    PS176是一个显示端口 (DP)至HDMI 2.0视频接口转换器适用于需要视频协议转换的电缆适配器.电视接收器.监视器和其他应用.它将接受任何显示端口输入格式,包括DP 1.1a.dp1.2a.dp ...

  3. 替代RTD2166|CS5212直接Pin to pin兼容替代RTD2166|替代RTD2166方案

    RTD2166功能概述 RTD2166是一款DisplayPort端口到VGA转换器,成本较高,Capstone于2019年推出CS5212,直接Pin to pin兼容替代RTD2166,可用原RT ...

  4. Linux时间与日期

    date date:显示当前时间[年月日时分秒] date +%[选项] Y:年 m:月 d:日 H:时 M:分 S:秒 date "+%Y-%m-%d":格式化显示,格式可自定. ...

  5. 从JVM设计角度解读Java内存模型

    第十六章:Java内存模型 本文我们将重点放在Java内存模型(JMM)的一些高层设计问题,以及JMM的底层需求和所提供的保证,还有一些高层设计原则背后的原理. 例如安全发布,同步策略的规范以及一致性 ...

  6. Window/Linux下Mysql的安装步骤

    Windows下Mysql安装教程 首先讲一下Windows环境下安装Mysql,我使用的安装包版本是mysql-8.0.26-winx64 下载地址:MySQL下载 1.点击上面的下载地址得到zip ...

  7. [Azure DevOps] 管理测试计划、测试套件和测试用例

    我喜欢测试计划,它能让团队清楚测试进度,还能妥善分配测试人员,更重要的是它能保证测试质量和效率.Azure DevOps 里提供了 Test Plans 这个模块用于管理测试计划. 1. Azure ...

  8. Word文档学习小练习链接

    1. < Word2010初学> https://www.toutiao.com/i6487370439910752782/ 2. <Word2010格式化可爱的家乡> htt ...

  9. Kotlin 协程一 —— 全面了解 Kotlin 协程

    一.协程的一些前置知识 1.1 进程和线程 1.1.1基本定义 1.1.2为什么要有线程 1.1.3 进程与线程的区别 1.2 协作式与抢占式 1.2.1 协作式 1.2.2 抢占式 1.3 协程 二 ...

  10. Android官方文档翻译 一 Getting Started

    Getting Started 让我们开始吧! Welcome to Training for Android developers. 欢迎来到Android开发者训练营. Here you'll f ...