luogu_P2051 [AHOI2009]中国象棋
时间:2019-10-31
本文章向大家介绍luogu_P2051 [AHOI2009]中国象棋,主要包括luogu_P2051 [AHOI2009]中国象棋使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
https://www.luogu.org/problem/P2051
题目描述
这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个炮,请问有多少种放置方法。大家肯定很清楚,在中国象棋中炮的行走方式是:一个炮攻击到另一个炮,当且仅当它们在同一行或同一列中,且它们之间恰好 有一个棋子。你也来和小可可一起锻炼一下思维吧!
输入格式
一行包含两个整数N,M,之间由一个空格隔开。
输出格式
总共的方案数,由于该值可能很大,只需给出方案数模9999973的结果。
输入输出样例
输入 #1
1 3
输出 #1
7
说明/提示
样例说明
除了3个格子里都塞满了炮以外,其它方案都是可行的,所以一共有2*2*2-1=7种方案。
数据范围
100%的数据中N和M均不超过100
50%的数据中N和M至少有一个数不超过8
30%的数据中N和M均不超过6
设出状态:
f[i][j][k]代表放了前i行,有j列是有一个棋子,有k列是有2个棋子的合法方案数.
(状态难想,但转移方程就比较明显)
转移:
一.第i行不放棋子
我们可以直接继承上面的状态.即f[i][j][k]=f[i-1][j][k]
二.第i行放一个棋子
三.第i行放两个棋子
#include<iostream> #include<cstdio> #define ri register int #define u long long namespace opt { inline u in() { u x(0),f(1); char s(getchar()); while(s<'0'||s>'9') { if(s=='-') f=-1; s=getchar(); } while(s>='0'&&s<='9') { x=(x<<1)+(x<<3)+s-'0'; s=getchar(); } return x*f; } } using opt::in; #define MO 9999973 #define NN 105 namespace mainstay { u N,M,f[NN][NN][NN]; inline u c_(const u &x){ return (x*(x-1)/2)%MO; } inline void solve() { N=(in()),M=(in()); f[0][0][0]=1; u m(M); for(ri i(1); i<=N; ++i) { for(ri j(0); j<=M; ++j) { for(ri k(0); k<=M; ++k) { if(j+k>M) continue; //不放 : f[i][j][k]=(f[i][j][k]+f[i-1][j][k])%MO; //在空白列放一个: if(j-1>=0) f[i][j][k]=(f[i][j][k]+f[i-1][j-1][k]*(M-k-j+1))%MO; // 在一个棋子列上放一个 if(k-1>=0) f[i][j][k]=(f[i][j][k]+f[i-1][j+1][k-1]*(j+1))%MO; //在空白列放两个 if(j-2>=0) f[i][j][k]=(f[i][j][k]+f[i-1][j-2][k]*c_(m-j-k+2))%MO; //在一个棋子列上放一个 ,并且在空白列放一个 if(k-1>=0) f[i][j][k]=(f[i][j][k]+f[i-1][j][k-1]*(M-j-k+1)*(j))%MO; //在一个棋子列上放两个 if(k-2>=0) f[i][j][k]=(f[i][j][k]+f[i-1][j+2][k-2]*c_(j+2))%MO; } } } u ans(0); for(ri i(0);i<=M;++i){ for(ri j(0);j<=M;++j){ if(i+j<=M) ans=(ans+f[N][i][j])%MO; } } std::cout<<ans; } } int main() { //freopen("T2.in","r",stdin); //freopen("T2.out","w",stdout); std::ios::sync_with_stdio(false); mainstay::solve(); }
原文地址:https://www.cnblogs.com/ling-zhi/p/11771907.html
- ORA-01427问题的分析和解决(r6笔记第51天)
- 从编程实现角度学习 Faster R-CNN(附极简实现)
- Java基础-23(02)总结多线程,线程实现Runnable接口,线程名字获取和设置,线程控制,线程安全,同步线程
- 8 个最好的 Java RESTful 框架
- 【C++基础】C++11 lambda 表达式解析
- 大量redo生成的问题原因及改进(r6笔记第50天)
- Java基础-22总结登录注册IO版,数据操作流,内存操作流,打印流,标准输入输出流,
- YOLO,一种简易快捷的目标检测算法
- Java基础-22总结转换流,随机访问流,合并流,序列化流,Properties
- openshift镜像构建
- 关于数据库无法登录的问题反思(r6笔记第49天)
- SQL中distinct的用法
- 数据结构是哈希表(hashTable)(一)
- 关于奇怪的并行进程分析(三)(r6笔记第47天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 前端国际化辅助工具——自动替换中文并翻译
- Codeforces Round #613 (Div. 2)A. Mezo Playing Zoma
- PAT (Advanced Level) Practice 1096 Consecutive Factors (20 分)
- Codeforces Round #613 (Div. 2)B. Just Eat It!
- java线程池(六):ForkJoinPool源码分析之二(WorkQueue源码)
- Codeforces Round #605 (Div. 3) D. Remove One Element
- 用python爬虫,pyinstaller写一个属于自己的彩虹屁生成器!
- 2020牛客寒假算法基础集训营4 C 子段乘积
- Callable and Future in Java(java中的Callable和Future)
- Java类 初步学习
- Gephi可视化拓扑图简单实战
- python连接到SQList数据库以及简单操作
- 在markdown编辑器使用html绘制表格
- 循环不变式:算法中基础概念的明晰
- Codeforces Round #615 (Div. 3)B. Collecting Packages