题目链接:HDOJ - 5155

题目大意

有一个 n * m 的棋盘,已知每行每列都至少有一个棋子,求可能有多少种不同的棋子分布情况。答案对一个大素数取模。

题目分析

算法1:

  使用容斥原理与递推。

  首先,一个 n * m 的棋盘不考虑任何限制时,可能的分布情况为 2^(n*m) ,除去没有棋子的情况,为 2^(n*m) - 1 。

  然后,因为所有的 n 行,m 列都有棋子,所以枚举 ii (1 <= ii <= i) , jj (1 <= jj <= j) 。对于枚举的一组 (ii, jj) ,若 (ii, jj) != (i, j) ,f[i][j] 就是恰好有 i 行 j 列都有棋子的情况数,再乘上在 i 行中选 ii 行 ( C[i][ii] ) ,在 j 列中选 jj 列的情况数( C[j][jj] ),就是在 i * j 的棋盘中,恰好有 ii 行, jj 列有棋子的情况数。(i, j) 的答案 f[i][j] 要减去这个值。

  这样就递推出了所有的 f[i][j] 。时间复杂度 O(n^4) 。

  注意的问题:组合数用递推来求。 C[i][0] = 1, C[i][j] = C[i-1][j-1] + C[i-1][j]; 进行递推时注意取模之后的数相乘会爆 Int 。

算法2:

  考虑一种 DP ,使用 f[i][j] 表示前 i 行都有棋子,然而只有 j 列有棋子的方案数。

  那么我们考虑第 i + 1 行的棋子放置情况,我们枚举第 i + 1 行棋子放置的个数 k ,再枚举这 k 个棋子中有 t 个放在之前没有棋子的列中。

  那么就有一个状态转移 : f[i+1][j+t] += f[i][j] * C[j][k-t] * C[m-j][t] 。

  时间复杂度同样是 O(n^4) 。

代码

算法1

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm> using namespace std; const int MaxN = 50 + 5, Mod = 1000000007; int n, m;
int C[MaxN][MaxN], f[MaxN][MaxN], Pow2[MaxN * MaxN]; void Init_C() {
C[0][0] = 1;
for (int i = 1; i <= 50; ++i) {
C[i][0] = 1;
for (int j = 1; j <= i; ++j) {
C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
C[i][j] %= Mod;
}
}
Pow2[0] = 1;
for (int i = 1; i <= 2500; ++i) {
Pow2[i] = Pow2[i - 1] << 1;
Pow2[i] %= Mod;
}
} typedef long long LL; int main()
{
Init_C();
for (int i = 1; i <= 50; ++i) {
for (int j = 1; j <= 50; ++j) {
f[i][j] = Pow2[i * j] - 1;
for (int ii = 1; ii <= i; ++ii) {
for (int jj = 1; jj <= j; ++jj) {
if (ii == i && jj == j) continue;
f[i][j] -= (LL)f[ii][jj] % Mod * (LL)C[i][ii] % Mod * (LL)C[j][jj] % Mod;
f[i][j] %= Mod;
}
}
f[i][j] = (f[i][j] + Mod) % Mod;
}
}
while (scanf("%d%d", &n, &m) != EOF) {
if (n == 0 || m == 0) {
printf("1\n"); continue;
}
printf("%d\n", f[n][m]);
}
return 0;
}

  

算法2就不写代码了。

最新文章

  1. win8.1中安装sql2014 0x800F0906 【 Error while enabling Windows feature : NetFx3, Error Code : -2146498298 】
  2. 由“js跨域”想到&quot;AJAX也不一定要XMLHttpRequest&quot;
  3. 关于Java中的GUI事件处理
  4. 工作点滴积累(1)---MD5和编码
  5. hibernate中使用fetch来决策性能方案
  6. &#39;mysql&#39; 不是内部或外部命令,也不是可运行的程序或批处理文件的解决办法
  7. 大设计时代:针对超大网页布局的一些思考和建议 [Aseoe]
  8. oracle学习总结1
  9. rpm不用yum安装rabbitMQ
  10. 《Maven实战》 第7章 生命周期与插件
  11. iptables 命令详解
  12. 【Rain in ACStar HDU-3340】
  13. nginx ../logs/nginx.pid&quot; failed (2: No such file or directory)
  14. 如何使用 Docker 来限制 CPU、内存和 IO等资源?
  15. Quartus prime 16.0 中通过JTAG固化程序
  16. NBUT1457
  17. word之删除图标目录之间的空行
  18. Shell - 简明Shell入门06 - 循环语句(Loop)
  19. vsphere HA内幕变化
  20. Java对象的强、软、弱和虚引用+ReferenceQueue

热门文章

  1. EXCEL 如何将多个工作表或工作簿合并到一个工作表
  2. 粗谈pcap_next_ex()
  3. linux 管道--转
  4. 通过SSHFS在RHEL中安全的挂载远程Linux/UNIX目录或文件系统--转载
  5. HTML5 &lt;Audio/&gt;标签Api整理(二)
  6. 使用Convert 类和Parse方法将字符串转换为数值类型
  7. vim字符串替换
  8. 获取IP所在地
  9. 后台线程,优先级,sleep,yield
  10. CentOS 7重装mysql编译过程报错解决方法