Chess

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 351    Accepted Submission(s): 124

Problem Description
小度和小良最近又迷上了下棋。棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M)。在他们的规则中,“王”在棋盘 上的走法遵循十字路线。也就是说,如果“王”当前在(x,y)点,小度在下一步可以移动到(x+1, y), (x-1, y), (x, y+1), (x, y-1), (x+2, y), (x-2, y), (x, y+2), (x, y-2) 这八个点中的任意一个。


  图1 黄色部分为棋子所控制的范围
  小度觉得每次都是小良赢,没意思。为了难倒小良,他想出了这样一个问题:如果一开始“王”在(x0,y0)点,小良对“王”连续移动恰好K步,一共可以有多少种不同的移动方案?两种方案相同,当且仅当它们的K次移动全部都是一样的。也就是说,先向左再向右移动,和先向右再向左移动被认为是不同的方案。
  小良被难倒了。你能写程序解决这个问题吗?

Input
输入包括多组数据。输入数据的第一行是一个整数T(T≤10),表示测试数据的组数。
每组测试数据只包括一行,为五个整数N,M,K,x0,y0。(1≤N,M,K≤1000,1≤x0≤N,1≤y0≤M)
Output
对于第k组数据,第一行输出Case #k:,第二行输出所求的方案数。由于答案可能非常大,你只需要输出结果对9999991取模之后的值即可。
Sample Input
2 2 2 1 1 1 2 2 2 1 1
Sample Output
Case #1: 2 Case #2: 4
Source
2014年百度之星程序设计大赛 - 初赛(第二轮)
题目分析:
最朴素的思想是每个点不断向旁边扩散,每个点第k次的方案数为sum(所有能到这个点的第(k-1)次所在的点的方案数之和),最终答案就是第k次所有点的方案数之和,复杂度大约是O(k*n*m),系数8,所以超时是定定的。
那么暴力不行我们应该怎么办?可以将横着走和竖着走拆开来考虑,因为这是互不影响的。设起点为(x0, y0),row[k][i]为第k步从起点走到纵坐标为 i 的方案数,col[k][i]为第k步从起点走到横坐标为 i 的方案数那么从起点(x0,y0)到(x,y)走k步的方案数即sum(col[k - d][x] * row[d][y])(d <— 0~k)。将所有横着走d步的方案累加得到cnt[0][d],所有竖着走d步的方案累加得到cnt[1][d],由排列组合可知,从横着走选d步,从竖着走选k - d步的组合数为C(k,d)。那么答案就是sum(C(k,d))(d <— 0~k)。算法的时间复杂度大约为O(n * m),十分优秀了~。
由于状态只于前一次有关,所以用了滚动数组优化,代码如下:

#include <stdio.h>
#include <string.h>
#define MS0(X) memset(X, 0, sizeof(X))
#define REP(i, a, b) for(int i = a; i <= b; ++i)
typedef long long ll;
const int O = 1005;
const int mod = 9999991;
int col[2][O], row[2][O], cnt[2][O], C[O][O], cur;
int n, m, k, x, y, t, cas;
void work(){scanf("%d%d%d%d%d", &n, &m, &k, &x, &y);MS0(col); MS0(row); MS0(cnt);cur = 0;col[0][y] = row[0][x] = cnt[0][0] = cnt[1][0] = 1;REP(i, 1, k){cur ^= 1;MS0(col[cur]); MS0(row[cur]);REP(j, 1, m){if(j - 2 >= 1) col[cur][j] += col[cur ^ 1][j - 2];if(j - 1 >= 1) col[cur][j] += col[cur ^ 1][j - 1];if(j + 1 <= m) col[cur][j] += col[cur ^ 1][j + 1];if(j + 2 <= m) col[cur][j] += col[cur ^ 1][j + 2];col[cur][j] %= mod;cnt[0][i] = (cnt[0][i] + col[cur][j]) % mod;}REP(j, 1, n){if(j - 2 >= 1) row[cur][j] += row[cur ^ 1][j - 2];if(j - 1 >= 1) row[cur][j] += row[cur ^ 1][j - 1];if(j + 1 <= n) row[cur][j] += row[cur ^ 1][j + 1];if(j + 2 <= n) row[cur][j] += row[cur ^ 1][j + 2];row[cur][j] %= mod;cnt[1][i] = (cnt[1][i] + row[cur][j]) % mod;}}ll ans = 0;REP(i, 0, k){ans = (ans + (((ll) cnt[0][i] * cnt[1][k - i]) % mod) * C[k][i]) % mod;}printf("%I64d\n", ans);
}
int main(){REP(i, 0, O - 1) C[i][0] = 1;REP(i, 1, O - 1) REP(j, 1, i) C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;for(scanf("%d", &t), cas = 1; cas <= t; ++cas){printf("Case #%d:\n", cas);work();}return 0;
}

HDU 4832

转载于:https://www.cnblogs.com/ac-luna/p/3754909.html

HDU 4832 Chess 排列组合 DP相关推荐

  1. hdu 4489(排列组合+DP)

    有N个高矮不同的人,求高矮高矮高矮高矮......或者矮高矮高矮高......的排列方法一共有多少种. 假设第N个插入到队伍中的人比前N-1个人都要高,假设他插入的位置为 j ,那么j-1要比j-2矮 ...

  2. HDU - 4489 The King’s Ups and Downs (排列组合+dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4489点击打开链接 The King's Ups and Downs Time Limit: 2000/ ...

  3. Tyler and Strings(树状数组/排列组合/dp)

    题目 题意:给定两个数组s,ts,ts,t,现重排列数组sss,使得数组sss小于ttt.问有多少种排列方式. 参考 代码源自cwxzh #include<bits/stdc++.h> u ...

  4. HDU 4832(DP+计数问题)

    HDU 4832 Chess 思路:把行列的情况分别dp求出来,然后枚举行用几行.竖用几行,然后相乘累加起来就是答案 代码: #include <stdio.h> #include < ...

  5. 2017ACM暑期多校联合训练 - Team 8 1011 HDU 6143 Killer Names (容斥+排列组合,dp+整数快速幂)...

    题目链接 Problem Description Galen Marek, codenamed Starkiller, was a male Human apprentice of the Sith ...

  6. bzoj 3398 [Usaco2009 Feb]Bullcow 牡牛和牝牛——前缀和优化dp / 排列组合

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3398 好简单呀.而且是自己想出来的. dp[ i ]表示最后一个牡牛在 i 的方案数. 当前 ...

  7. 走方格跳格子(dp,递归,排列组合三种方法)

    走方格: 给定一个 n×mn×m 的方格阵,沿着方格的边线走,从左上角 (0,0)(0,0) 开始,每次只能往右或者往下走一个单位距离,问走到右下角 (n,m)(n,m) 一共有多少种不同的走法. 输 ...

  8. 用DP解决排列组合问题

    高中时学过的排列组合问题,蕴含着一种动态规划的思想,即: 若用二维数组的概念,即: ,但此处若不是简单的组合数,就应该对公式进行修改,根据题意来加一些其他条件. 如例题(印章),python代码如下: ...

  9. 排列组合,字符串——Killer Names

    **题目:**Problem - 6143 http://acm.hdu.edu.cn/showproblem.php?pid=6143 Killer Names Time Limit: 2000/1 ...

最新文章

  1. 初中计算机教师资格考试试题,2017下半年初中信息技术教师资格证面试试题(精选)第一批(2)...
  2. 1047. Student List for Course (25)
  3. Windows 令人“社死”的新功能,你都知道吗?
  4. 云数据库RDS基础版的优势及适用场景
  5. Python程序,辅助微信跳一跳游戏介绍
  6. Sentinel的简单使用
  7. java 类加载器卸载,【深入明白Java虚拟机 】类加载器的命名空间以及类的卸载...
  8. ssh登录慢的解决办法
  9. 图的m着色问题回溯法求解
  10. java基于springboot小区水电量电费管理系统
  11. iPhone各机型屏幕尺寸
  12. 微积分:如何理解多元函数可微和全微分?
  13. eda交通灯控制器波形输入_EDA实验报告实验四:交通灯控制器设计
  14. dflow入门2——Slices
  15. Linux 安装NDK
  16. 进击的“懒人经济”,快手又迎来一个万亿蓝海市场
  17. 惊爆:江民公司官方网站今日被黑
  18. 利用BSCScan获取账户交易记录
  19. vmware中linux连接不上wifi
  20. 点餐系统架构模型_餐馆点餐系统课程设计

热门文章

  1. mysql -s 参数_mysqldump 的常用参数。
  2. Python 与 SQLServer数据库连接
  3. 【github干货】主流深度学习开源框架从入门到熟练
  4. 迅雷的user-agent
  5. 日本农商巨头50年布局多个领域 对话国际农民丰收节贸易会
  6. openresty开发系列37--nginx-lua-redis实现访问频率控制
  7. ASTreeView Demo:Add, Edit Delete nodes
  8. 更新android应用到最新版本
  9. Android学习笔记--JNI的使用方法
  10. struts2注解json 配置文件json