【问题描述】

【题解】

先考虑一个最简单的情况。如一个n*n的棋盘。然后要放k个车。

我们可以先选出k行即C(n,k);

然后在列上对这k个棋子进行一次全排列即A(n,k);

比如k = 4;N=5

选的行为1,2,3,4

然后枚举的列1,2,3,4和4,3,2,1

前者表示第一行放在1,第二行放在2,。。。第4行放在4.(列)

后者表示第一行放在4,第二行放在3.。。。第4行放在1的位置.(列)

这是进行全排列的原因。

然后答案就是C(n,k)*A(n,k);

然后把原题的图切成下面的样子

然后在上面的小矩形内枚举放置i个棋子。

方案就是C(b,i)*A(a,i);

在下面。因为左边被占据了i列。所以下面可以用的只剩下a+c-i列。

可以看成是一个长为a+c-i,宽为d的矩形。

则在下面的方案为C(d,k-i)*A(a+c-i,k-i);

然后对于枚举的i,如果可行。则答案递增C(b,i)*A(a,i)*C(d,k-i)*A(a+c-i,k-i)

要记得取模。

然后组合数可以用C[i][j] = c[i-1][j]+c[i-1][j-1]得到。

然后因为

所以要求排列数可以用组合数乘上一个k!

一边取模就可以了。

然后因为C(b,i)*A(a,i)*C(d,k-i)*A(a+c-i,k-i) 中出现了a+c-i。所以把组合数开到[2000][2000]

不然会错!而且编译器不会告诉你数组越界了!

还有一种分法。

则对于枚举的i变成递增答案C(d,i)*A(c,i)+C(b+d-i,k-i)*A(a,k-i);

【代码】--按照第一种分法做的。

#include <cstdio>
#include <stdlib.h> const int mo = 100003;
long long A[2001][2001], C[2001][2001], N1[2001], ans = 0; //乘的时候可能会超过int类型所以用Longlong了。
int a, b, c, d, k; void init()
{
for (int i = 0; i <= 2000; i++) //获取组合数
C[i][0] = 1, C[i][i] = 1;
for (int i = 1; i <= 2000; i++)
for (int j = 1; j <= i; j++)
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mo;
N1[0] = 1;
for (int i = 1; i <= 2000; i++) //获取1到2000的阶乘,当然都是取模后的结果。
N1[i] = (N1[i - 1] * i) % mo;
for (int i = 0; i <= 2000; i++) //用相应的组合数来获取排列数。
for (int j = 0; j <= i; j++)
A[i][j] = (C[i][j] * N1[j]) % mo;
} int min(int a, int b) //返回a和b中的较小值。
{
return a>b ? b : a;
} void input_data()
{
scanf("%d%d%d%d%d", &a, &b, &c, &d, &k);//输入数据
int maxk = min(a, b); //这是在上面那个小矩形内能够放下的最大的车的数量
for (int i = 0; i <= maxk; i++) //枚举在那个小矩形内放几个车
{
if ((k - i) > d) continue;
if ((a + c - i)<(k - i)) continue; //如果下面的大矩形不能放下剩余的k-i个车则跳过
ans = (ans + ((((C[b][i] * A[a][i]) % mo)*((C[d][k - i] * A[a + c - i][k - i]) % mo)) % mo)) % mo;
//否则按照题解的思路递增答案。
}
} void output_ans()
{
printf("%I64d", ans);
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
//freopen("F:\\rush_out.txt", "w", stdout);
//freopen("place.in","r",stdin);
//freopen("place.out","w",stdout);
init();
input_data();
output_ans();
//fclose(stdin);
// fclose(stdout);
return 0;
}

最新文章

  1. Winform 窗体最小化隐藏在桌面右下角:转
  2. Objective-C学习笔记---构造函数和析构函数
  3. js闭包理解实例小结
  4. YII 1.0 增删改查
  5. 合并查询结果集UNION(去重), UNION ALL(不去重),INTERSECT(交集),MINUS(差集,第一个结果集减去第二个结果集,第一个结果集中不在第二个结果集中的记录行),[NOT] EXIST
  6. 一种优雅的条件引用第三方.net库的方法
  7. “Excel-建议不可用于您所选择的数据”错误提示
  8. 【vue】使用localStorage解决vuex在页面刷新后数据被清除的问题
  9. ThinkPHP 缓存技术详解 使用大S方法
  10. delphi 通过事务插入数据
  11. springMVC数据模型model,modelmap,map,@ModelAttribute的相互关系
  12. mac下快速安装gearman和php扩展
  13. 跟厂长学PHP7内核(二):源码分析的环境与工具
  14. NetCore+Dapper WebApi架构搭建(三):添加实体和仓储
  15. JZOJ.5331【NOIP2017模拟8.23】壕游戏
  16. hiho一下 第二周 trie树
  17. 《DSP using MATLAB》 Problem 2.3
  18. Access to the path ‘’ is denied
  19. Python实例---三级菜单的实现[high]
  20. 1spring注解:@Configuration,@Bean,@ComponentScan(),@Scope

热门文章

  1. 洛谷 P1626 象棋比赛
  2. 5.9 enum--支持枚举类型
  3. Jszip的使用和打包下载图片
  4. IDEA配置svn地址方法及出现的问题的解决办法
  5. 原生js大总结十一
  6. 不在JPA 的 persistence.xml 文件中配置Entity class的解决办法
  7. MYSQL添加远程用户或允许远程访问三种方法
  8. Java Timer TimerTask Example(java Timer的例子)
  9. Android 调用系统邮件,发送邮件到指定邮箱
  10. 使用DNSCrypt解决Dropbox污染问题