BZOJ1801或洛谷2051 [AHOI2009]中国象棋
BZOJ原题链接
洛谷原题链接
这题挺难想状态的,刚看题感觉是状压,但数据\(100\)显然不可能。
注意到每行每列只能放\(0\sim 2\)个棋子,所以我们可以将这个写入状态。
设\(f[i][j][k]\)表示放了前\(i\)行,共有\(j\)列只放了一个棋子,共有\(k\)列放了两个棋子,而没有放棋子的列数则可以直接计算,即\(m - j - k\)。
然后分类讨论。
- 第\(i\)行不放
只有一种放法,直接由上一层转移:$$f[i][j][k] = f[i][j][k] + f[i - 1][j][k]$$
- 第\(i\)行放一个棋子
- 放在原本没有放棋子的列上,共\(m - (j - 1) - k\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j - 1][k] \times (m - (j - 1) - k)$$
- 放在原本只有一个棋子的列上,共\(j + 1\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j + 1][k - 1] \times (j + 1)$$
- 第\(i\)行放两个棋子
- 都放在原本没有放棋子的列上,共\(C_{m - (j - 2) - k} ^ 2\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j - 2][k] \times C_{m - (j - 2) - k} ^ 2$$
- 一个放在空列,一个放在原本只有一个棋子的列上,共\(j \times (m - j - (k - 1))\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j][k - 1] \times j \times (m - j - (k - 1))$$
- 都放在原本只有一个棋子的格子上,共\(C_{j + 2} ^ 2\)种放法:$$f[i][j][k] = f[i][j][k] + f[i - 1][j + 2][k - 2] \times C_{j + 2} ^ 2$$
初值\(f[0][0][0] = 1\),其它为\(0\)。
在\(DP\)过程中注意取模和边界问题。
最后答案就是\(\sum\limits_{i = 0} ^ m \sum \limits _{j = 0} ^ m f[n][i][j]\)。
#include<cstdio>
using namespace std;
const int N = 110;
const int mod = 9999973;
int f[N][N][N];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
inline int C(int x)
{
return (1LL * x * (x - 1) >> 1) % mod;
}
int main()
{
int i, j, k, n, m, s = 0;
n = re();
m = re();
f[0][0][0] = 1;
for (i = 1; i <= n; i++)
for (j = 0; j <= m; j++)
for (k = 0; k + j <= m; k++)
{
f[i][j][k] = f[i - 1][j][k];
if (k)
{
f[i][j][k] = ((1LL * f[i - 1][j + 1][k - 1] * (j + 1) % mod) + f[i][j][k]) % mod;
f[i][j][k] = ((1LL * f[i - 1][j][k - 1] * j % mod * (m - j - k + 1) % mod) + f[i][j][k]) % mod;
}
if (j)
f[i][j][k] = ((1LL * f[i - 1][j - 1][k] * (m - j - k + 1) % mod) + f[i][j][k]) % mod;
if (j > 1)
f[i][j][k] = ((1LL * f[i - 1][j - 2][k] * C(m - j - k + 2) % mod) + f[i][j][k]) % mod;
if (k > 1)
f[i][j][k] = ((1LL * f[i - 1][j + 2][k - 2] * C(j + 2) % mod) + f[i][j][k]) % mod;
}
for (i = 0; i <= m; i++)
for (j = 0; j <= m; j++)
s = (1LL * s + f[n][i][j]) % mod;
printf("%d", s);
return 0;
}
BZOJ1801或洛谷2051 [AHOI2009]中国象棋的更多相关文章
- 洛谷.2051.[AHOI2009]中国象棋(DP)
题目链接 /* 每行每列不能超过2个棋子,求方案数 前面行对后面行的影响只有 放了0个.1个.2个 棋子的列数,与排列方式无关 所以设f[i][j][k]表示前i行,放了0个棋子的有j列,放了1个棋子 ...
- 洛谷2051 [AHOI2009]中国象棋
题目链接 题意概述:n行m列棋盘放若干个棋子每行每列最多两个求方案总数,答案对9999973取模. 可以比较容易看出这是个dp,设f[i][j][k]表示前i行j列放1个棋子k列放2个棋子的方案总数. ...
- [洛谷P2051] [AHOI2009]中国象棋
洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...
- 洛谷 P2051 [AHOI2009]中国象棋 解题报告
P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...
- 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP
P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...
- 洛谷 P2051 [AHOI2009]中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- 洛谷P2051 [AHOI2009]中国象棋(dp)
题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\( ...
- 洛谷P2051 [AHOI2009] 中国象棋(状压dp)
题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...
- luogu 2051 [AHOI2009]中国象棋
luogu 2051 [AHOI2009]中国象棋 真是一道令人愉♂悦丧心并框的好题... 首先"没有一个炮可以攻击到另一个炮"有个充分条件就是没有三个炮在同一行或同一列.证明:显 ...
随机推荐
- gradle 很好用的么
Gradle 其实是很好用的 2017, Apr 14 by Tesla Ice Zhang Gradle 是一款使用 Kotlin (划掉) Groovy 编写的 JVM 构建工具,其易用性和 Ma ...
- boot中 Quartz注入spring管理类失败
在项目中用到了Quartz,想在里面实现业务操作发现sping类注入总是失败.后来网上查询了一下解决办法.下面把我成功解决问题的这个版本发出来,大家一起学习一下. 在quartz 会发现 job中无法 ...
- 签名Cookie
[签名Cookie] set-cookie时加上防篡改验证码. 如: user_name=alex|bj95ef23cc6daecc475de 防篡改验证码的生成规则可以很简单:md5(cooki ...
- Python调用sqlAlchemy
import logging from sqlalchemy import Column, String, create_engine from sqlalchemy.ext.declarative ...
- json数组转java对象
<dependency> <groupId>net.sf.json-lib</groupId> <artifactId>ison-lib</art ...
- linux重新安装python
第一步:下载python2.7 wget https://www.Python.org/ftp/python/2.7.12/Python-2.7.12.tar.xz 第二步: 解压刚刚下载的压缩包 ...
- 一、Blender/Python 快速入门
原文:https://docs.blender.org/api/blender_python_api_current/info_quickstart.html#native-types 1 前言 可以 ...
- Android 设置EditText光标位置(转)
Android 设置EditText光标位置 最后 CharSequence text = edtTxt_my_account_edit_nickname.getText();if (text ins ...
- springboot jpa sql查询与传值
public interface ARepository extends PagingAndSortingRepository<A, APK>, JpaSpecificationExecu ...
- jsp页面之初体验
最近在学jsp 在web.xml页面中学到了如何让一个页面第一个启动