洛谷P2051 中国象棋
题目描述
这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法。大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子。你也来和小可可一起锻炼一下思维吧!
输入输出格式
输入格式:
一行包含两个整数N,M,之间由一个空格隔开。
输出格式:
总共的方案数,由于该值可能很大,只需给出方案数模9999973的结果。
输入输出样例
1 3
7
说明
样例说明
除了3个格子里都塞满了炮以外,其它方案都是可行的,所以一共有2*2*2-1=7种方案。
数据范围
100%的数据中N和M均不超过100
50%的数据中N和M至少有一个数不超过8
30%的数据中N和M均不超过6
首先可以知道可行的方案就是每行每列的放的炮数<=2
50%数据是状压dp,然后我们发现,他的矩形是规则的而且没有障碍一类的。
那么答案就跟他的每个具体排列没有直接关系,直接用dp[i][j]表示到当前行为止有多少炮数为1的列和炮数为2的列
由于每行也最多只能放两个炮,所以可以用dp[i][j]
转移到dp[i-1][j+1](有一个炮数为1的列在此行放上一个炮)
转移到dp[i+1][j](有一个炮数为0的列在此行放上一个炮)
转移到dp[i-2][j+2](有两个炮数为1的列在此行放上一个炮)
转移到dp[i+2][j](有两个炮数为0的列在此行放上一个炮)
转移到dp[i][j+1](有一个炮数为0的列在此行放上一个炮,有一个炮数为1的列在此行放上一个炮)
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=100+10,mod=9999973;
long long n,m,dp[maxn][maxn],f[maxn][maxn],ans; int main() {
scanf("%lld%lld",&n,&m);
dp[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) if(dp[j][k]){
if(j)f[j-1][k+1]=(f[j-1][k+1]+dp[j][k]*j%mod)%mod;
if(m-j-k)f[j+1][k]=(f[j+1][k]+dp[j][k]*(m-j-k)%mod)%mod; if(j>1)f[j-2][k+2]=(f[j-2][k+2]+dp[j][k]*j*(j-1)/2%mod)%mod;
if(m-j-k>1)f[j+2][k]=(f[j+2][k]+dp[j][k]*(m-j-k)*(m-j-k-1)/2%mod)%mod; if(m-j-k)f[j][k+1]=(f[j][k+1]+dp[j][k]*(m-j-k)*j%mod)%mod; f[j][k]=(f[j][k]+dp[j][k])%mod;
}
memcpy(dp,f,sizeof(f));memset(f,0,sizeof(f));
}
for(int j=0;j<=m;++j) for(int k=0;k<=m-j;++k) ans=(ans+dp[j][k])%mod;
printf("%lld",ans);
return 0;
}
洛谷P2051 中国象棋的更多相关文章
- 洛谷 - P2051 - 中国象棋 - 简单dp
https://www.luogu.org/problemnew/show/P2051 一点都不简单的简单dp. 还是从旧行转移到新行,而不是考虑新行从哪些旧行转移吧. #include<bit ...
- 洛谷P2051 中国象棋【dp】
题目:https://www.luogu.org/problemnew/show/P2051 题意:n*m的格子里放炮,使他们不能互相攻击. 如果两个炮在同一行同一列并且中间还有一个棋子的话就可以攻击 ...
- 洛谷P2051 中国象棋(dp)
题目链接:传送门 题目大意: 在N行M列的棋盘中放象棋中的“炮”,问要使得“炮”两两互不伤害,有多少种放法. 1 ≤ n,m ≤ 100,答案对9999973取模. 思路: 按行更新答案.每行炮可以放 ...
- 洛谷 [P2051] 中国象棋
DP orz__stdcall 首先要想出来,每行最多只能放两个棋子,这是显然的 于是决策就是一行一行地处理 30分的做法就是裸的枚举,暴搜,枚举这一行放哪里,放几个 然后想到了压位dp,按3进制表示 ...
- 洛谷 P2051 中国象棋 题解
题面 状态可能不太好想,设f[i][j][k]表示前i行其中有j行是放一个炮,有k行是放两个炮的合法方案数: 那么: f[i+1][j][k]+=f[i][j][k] 在这一行不放任何棋子: ...
- P2051 中国象棋
P2051 中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法.大家肯定很清楚,在中 ...
- [洛谷P2051] [AHOI2009]中国象棋
洛谷题目链接:[AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法 ...
- 洛谷 P2051 [AHOI2009]中国象棋 解题报告
P2051 [AHOI2009]中国象棋 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法. ...
- 洛谷 P2051 [AHOI2009]中国象棋 状态压缩思想DP
P2051 [AHOI2009]中国象棋 题意: 给定一个n*m的空棋盘,问合法放置任意多个炮有多少种情况.合法放置的意思是棋子炮不会相互打到. 思路: 这道题我们可以发现因为炮是隔一个棋子可以打出去 ...
随机推荐
- 用py3的nonlocal来打破局部变量间的作用域
nonlocal:用于局部变量,找上层中离当前函数最近一层的局部变量,找到为止,如果在全局找到或找不到,报错. 使用场景:内层函数对外层数据修改/处理
- 深入了解MVC(转)
MVC无人不知,可很多程序员对MVC的概念的理解似乎有误,换言之他们一直在错用MVC,尽管即使如此软件也能被写出来,然而软件内部代码的组织方式却是不科学的,这会影响到软件的可维护性.可移植性,代码的可 ...
- 数据库迁移工具DBMigration
- jnhs中国的省市县区邮编坐标mysql数据表
https://blog.csdn.net/sln2432713617/article/details/79412896 -- 1.之前项目中需要全国的省市区数据,在网上找了很多,发现数据要么不全,要 ...
- Python基础-列表、元组、字典、字符串
Python基础-列表.元组.字典.字符串 多维数组 nums1 = [1,2,3] #一维数组 nums2 = [1,2,3,[4,56]] #二维数组 nums3 = [1,2,3,4,['a ...
- python基础--魔法方法、迭代器、上下文管理
isinstance:判断一个对象是否是某个类的实例 参数一:要判断的对象 参数二:要判断的类型 issubclass:判断一个类是否是另一个类的子类 参数一:是待判断的子类 参数二:待判断的父类 _ ...
- 操作系统Lab1 详解(boot|kern/debug)
总体 : boot kern libs tools boot asm.h bootmain.c bootasm.S asm.h 汇编头文件 SEG_NULLASM 定义一个空段描述符 SEG_ASM ...
- Codeforces 1150D(字符串dp)
反思 三维的dp压根没看出来,看题解以后思路又很直观,找几道字符串dp练练才行 序列自动机和优化一维略 /* __ __ * ____| |_____| |____ * | | * | __ | * ...
- Django项目:CRM(客户关系管理系统)--04--02PerfectCRM创建ADMIN页面02
十.CRM项目创建模板页面 {#king_base.html#} {## ————————02PerfectCRM创建ADMIN页面————————#} {#模板文件 king_base.html#} ...
- 问题解决:在js中绑定onclick事件为什么不加括号,在html代码中必须要加?(转载)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...