BZOJ-1801-中国象棋
2016-04-19 21:44
423 查看
/* 从题可知每行每列不能超过2个棋子。 感觉类似求N皇后的方案数。 DP应该是可行的,但是不知道怎么设DP状态。 N行M列 网上看了下,设DP[i][j][k]为前 i 行 ,有 j 列棋子为一个,有 k 列棋子为两个的方案数 DP[0][0][0] = 1 那么对于第i行有以下几种情况 1.不放棋子 dp[i][j][k] += dp[i-1][j][k] 2.放一颗棋子 1).在没有棋子的一列中放一颗棋子 dp[i][j][k] += dp[i-1][j-1][k]*(M-k-j+1) 2).在原有一颗棋子的一列中放一颗棋子 dp[i][j][k] += dp[i-1][j+1][k-1]*(j+1) 3.放两个棋子 1).在没有棋子的两列中分别放下两颗棋子 dp[i][j][k] += dp[i-1][j-2][k]*C((M-k-j+2),2) 2).在原有一课棋子的两列分别放下一颗棋子 dp[i][j][k] += dp[i-1][j+2][k-2]*C(j+2,2) 3).一颗棋子放在没有棋子的一列,一颗棋子放在原有一颗棋子的一列 dp[i][j][k] += dp[i-1][j][k-1]*(M-j-k+1)*(j) */ #include <iostream> #define LL long long #define MOD 9999973 using namespace std; LL dp[110][110][110]; LL ans; inline LL C(LL a) { return (a*(a - 1)) >> 1; } int main() { int n, m; cin >> n >> m; dp[0][0][0] = 1; for (int i = 1; i <= n;i++) for (int j = 0; j <= m;j++) for (int k = 0; k <= m - j; k++) { dp[i][j][k] = dp[i - 1][j][k]; if (j) dp[i][j][k] += dp[i - 1][j - 1][k] * (m - k - j + 1); if (j < m&&k) dp[i][j][k] += dp[i - 1][j + 1][k - 1] * (j + 1); if (j>1) dp[i][j][k] += dp[i - 1][j - 2][k] * C((m - k - j + 2)); if (j + 1<m&&k > 1) dp[i][j][k] += dp[i - 1][j + 2][k - 2] * C(j + 2); if (j&&k) dp[i][j][k] += dp[i - 1][j][k - 1] * (m - j - k + 1)*(j); dp[i][j][k] %= MOD; } for (int i = 0; i <= m;i++) for (int j = 0; j <= m - i; j++) { ans = (ans + dp [i][j]) % MOD; } cout << ans << endl; return 0; }
相关文章推荐
- 傅里叶变换的解释与推导
- Linux 游戏服务器搭建教程详解
- Java迭代器的一般用法
- 测试说明书的概述和摘要
- 团队项目冲刺第二天
- 毕设今日总结(三)
- BZOJ-1800-飞行棋
- 4.结对编程汇编
- 算法题:两颗砖石谁轻谁重?
- 30 条 Android 开发建议 2016.3.16
- 将svn上文件同步到本地
- rz,sz是Linux
- gcc编译器
- 利用VGG_FACE来对性别数据进行finetune
- 关于tc的时间函数
- 程序员编码大赛第三届第二题
- centos6 常用重要命令
- com.sun.faces.config.ConfigureListener找不到报错
- poj1837——Balance(dp)
- VectorDrawable 怎么玩(Android)