洛谷.2051.[AHOI2009]中国象棋(DP)
/*
每行每列不能超过2个棋子,求方案数
前面行对后面行的影响只有 放了0个、1个、2个 棋子的列数,与排列方式无关
所以设f[i][j][k]表示前i行,放了0个棋子的有j列,放了1个棋子的有k列,则放了2个棋子的为(m-j-k)列
则放棋子一共可分为6种情况
不放棋子:1.f[i+1][j+2][k] += f[i][j][k]
放一个棋子:2.放在没有棋子的那一列 f[i+1][j-1][k+1] += f[i][j][k]*j
3.放在有棋子的那一列 f[i+1][j][k-1] += f[i][j][k]*k
放两个棋子:4.都放在没有棋子的两列 f[i+1][j-2][k+2] += f[i][j][k]*C(j,2)
5.都放在有一个棋子的两列 f[i+1][j][k-2] += f[i][j][k]*C(k,2)
6.一个放在没有棋子的一列,一个放在有一个棋子的一列 f[i+1][j-1][k] += f[i][j][k]*j*k
或用f[i][j][k]表示第i行,放了1个棋子的有j列,放了2个棋子的有k列,没放棋子的有(m-j-k)列
*/
#include<cstdio>
using namespace std;
const int N=105,mod=9999973;
int n,m;
long long f[N][N][N];//long long!
inline int C(int n)//C(n,2)
{
return n*(n-1)>>1;
}
//inline void Add(int /&n,int b)
//{
// n+=b;
// n-= n>=mod?mod:0;
//}
int main()
{
scanf("%d%d",&n,&m);
f[0][m][0]=1;
// f[0][0][0]=1;
for(int i=0;i<n;++i)
for(int j=0;j<=m;++j)
for(int k=0;k+j<=m;++k)
if(f[i][j][k])//0是无意义的
{
// f[i+1][j][k]=(f[i+1][j][k]+f[i][j][k])%mod;
// if(m-k-j>=1) f[i+1][j+1][k]=(f[i+1][j+1][k]+f[i][j][k]*(m-k-j))%mod;
// if(j) f[i+1][j-1][k+1]=(f[i+1][j-1][k+1]+f[i][j][k]*j)%mod;
// if(m-k-j>=2) f[i+1][j+2][k]=(f[i+1][j+2][k]+f[i][j][k]*C(m-k-j))%mod;
// if(j>=2) f[i+1][j-2][k+2]=(f[i+1][j-2][k+2]+f[i][j][k]*C(j))%mod;
// if(m-k-j>=1 && j>=1) f[i+1][j][k+1]=(f[i+1][j][k+1]+f[i][j][k]*(m-k-j)*j)%mod;
//注意 && j>=1!虽然能得到一个j,但条件中必须有一个j
f[i+1][j][k]=(f[i+1][j][k]+f[i][j][k])%mod;//不放不会增加不放棋子的列数!
if(j>=1) f[i+1][j-1][k+1]=(f[i+1][j-1][k+1]+f[i][j][k]*j%mod)%mod;
if(k>=1) f[i+1][j][k-1]=(f[i+1][j][k-1]+f[i][j][k]*k%mod)%mod;
if(j>=2) f[i+1][j-2][k+2]=(f[i+1][j-2][k+2]+f[i][j][k]*C(j)%mod)%mod;
if(k>=2) f[i+1][j][k-2]=(f[i+1][j][k-2]+f[i][j][k]*C(k)%mod)%mod;
if(j>=1 && k>=1) f[i+1][j-1][k]=(f[i+1][j-1][k]+f[i][j][k]*j*k%mod)%mod;
//跑得慢。。懵逼
}
long long res=0;
for(int i=0;i<=m;++i)//枚举不放的列
for(int j=0;i+j<=m;++j)//枚举放一个的列
res=(res+f[n][i][j])%mod;//两种确定,第三种列也确定
printf("%lld",res);
return 0;
}
洛谷.2051.[AHOI2009]中国象棋(DP)的更多相关文章
- BZOJ1801或洛谷2051 [AHOI2009]中国象棋
BZOJ原题链接 洛谷原题链接 这题挺难想状态的,刚看题感觉是状压,但数据\(100\)显然不可能. 注意到每行每列只能放\(0\sim 2\)个棋子,所以我们可以将这个写入状态. 设\(f[i][j ...
- 洛谷P2051 [AHOI2009]中国象棋(dp)
题面 luogu 题解 \(50pts:\)显然是\(3\)进制状压\(dp\) \(100pts:\) 一行一行地考虑 \(f[i][j][k]\)表示前\(i\)行,有\(j\)列放了一个,有\( ...
- 洛谷2051 [AHOI2009]中国象棋
题目链接 题意概述:n行m列棋盘放若干个棋子每行每列最多两个求方案总数,答案对9999973取模. 可以比较容易看出这是个dp,设f[i][j][k]表示前i行j列放1个棋子k列放2个棋子的方案总数. ...
- 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP
P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...
- [洛谷P2051] [AHOI2009]中国象棋
洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...
- 洛谷 P2051 [AHOI2009]中国象棋 解题报告
P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...
- 洛谷 P2051 [AHOI2009]中国象棋
题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中国象棋中炮的行走方式是 ...
- 洛谷P2051 [AHOI2009] 中国象棋(状压dp)
题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...
- Luogu 2051[AHOI2009]中国象棋 - DP
Description 在 $n * m$ 的格子上放若干个炮, 使得每个炮都不能攻击到其他炮 Solution 定义数组f[ i ][ j ][ k ] 表示到了第 i 行, 已经有2个炮的列数为 ...
随机推荐
- sync_binlog innodb_flush_log_at_trx_commit 浅析【转】
innodb_flush_log_at_trx_commit和sync_binlog 两个参数是控制MySQL 磁盘写入策略以及数据安全性的关键参数.本文从参数含义,性能,安全角度阐述两个参数为不同的 ...
- dubbo系列三、架构介绍及各模块关系
一.整体设计 图例说明: 图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口. 图中从下至上分为十层,各层均为单向依赖,右边的黑色箭头代 ...
- python实现监控windows服务控制开关服务
转载自 :http://www.jb51.net/article/49106.htm #!/usr/bin/env python #-*- encoding:utf-8 -*- "" ...
- spring+activemq配置文件内容及实现原理
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Android开源动画库nineoldandroids
项目官网地址:http://nineoldandroids.com/ 使用这个库的原因是android3.0之后出了新的animation API,但是android3.0以下的不支持 这个库完成了这 ...
- UITableView滑动性能优化扩展
一点UITableView滑动性能优化扩展 影响UITableView的滑动,有哪些因素呢? 关于这一点,人眼能识别的帧率是60左右,这也就是为什么,电脑屏幕的最佳帧率是60Hz. 屏幕一秒钟会刷 ...
- 前端工程化-webpack(打包JS)(二)
一.第一种打包方式 webpack entry<entry> output 假设目录结构如下: index.html是入口文件 打包app.js为bundle.js如下 app.js 当使 ...
- Java中强、软、弱、虚引用
1.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使 ...
- linux eclipse 报错过时的方法
重新配置jre库 https://jingyan.baidu.com/article/7f766daff5b8cd4101e1d0b4.html
- zoj3469 区间dp好题
/* 按坐标排序 以餐厅为起点向两边扩展区间 dp[i][j][0]表示送完区间[i,j]的饭后停留在左边的代价 dp[i][j][1]表示送完区间[i,j]的饭后停留在右边的代价 */ #inclu ...