P3977 [TJOI2015] 棋盘题解

news/2025/10/1 22:07:23/文章来源:https://www.cnblogs.com/2021hych/p/19122952

题目描述

有个 \(n\)\(m\) 列的棋盘,棋盘上可以放许多棋子。每个棋子的攻击范围是 \(3\)\(p\) 列。输入数据用一个 \(3\times p\) 的矩阵给出了棋子攻击范围的模板,棋子被默认为模板中的第 \(2\) 行,第 \(k+1\) 列,则棋子能攻击到的位置是 \(1\),不能攻击到的位置是 \(0\)。输入数据保证第 \(2\) 行第 \(k+1\) 列的位置是 \(1\)。求在棋子互相不能攻击到的前提下,摆放棋子的方案数,答案对 \(2^{32}\) 取余数。

对于 \(100\%\) 的数据,\(1 \leq n \leq 10^{6}\)\(1 \leq m \leq 6\)

题目分析

\(m\) 很小,考虑状压 \(\text{DP}\)

第一步,状压。对于每一行的摆放棋子的情况,我们用二进制压缩,\(0\) 代表改位置不摆放,反之为 \(1\)

第二步,状态总量简化。首先并非 \([0,2^m-1]\) 都是合法行状态,通过枚举,将合法状态存在一个数组 \(S\) 中,这将是之后 \(\text{DP}\) 转移时的可行方案库!

一个小小的问题是,如何利用给定的棋子攻击范围的模板,来快速判断行状态是否合法?显然,行状态的合法性取决于第二行的攻击模板,但是由于攻击模板是以 \(k+1\) 为基准的,所以我们枚举待判定的行中的所有 \(1\),将攻击模板左移 \(\text{or}\) 右移使得 \(k+1\) 与该位置对齐,判断平移后的攻击模板是否与待判定的行有重叠即可(即按位或结果是否非零),这部分的复杂度是 \(O(m)\) 的,因此第二步的总复杂度为 \(O(m2^m)\)

第三步,\(\text{DP}\)。由于棋子攻击范围的模板只有三行,所以转移只需考虑上一行的情况即可。设 \(dp_{i,j}\) 表示第 \(i\) 行摆放棋子的方案为 \(S_j\) 时,前 \(i\) 行构成的子棋盘的所求方案数。则:

\[dp_{i,j}=\sum\limits_{t = 1}^{|S|}{dp_{i-1,t}[check(S_t,S_j)]} \]

其中求和中的括号为艾弗森括号,\(check(S_t,S_j)\) 表示 \(S_t\) 在上一行是否会与 \(S_j\) 冲突。判断方法由第二步如法炮制即可。\(\text{DP}\) 的总复杂度是 \(O(nm(2^m)^2)\)。预处理 \(check\) 的所有情况则可做到 \(O(n4^m)\),由于 \(n\) 很大,这样的做法是很难通过本题的。

第四步,优化。显然这个算法的瓶颈在于 \(n\),但是如何才能把 \(n\) 优化掉呢?在众多 \(\text{DP}\) 优化中,最常见的对 \(n\) 优化的方法当属矩阵加速(快速幂)。因此我们用矩阵的眼光重新梳理转移式:

\[\begin{pmatrix} dp_{i,1} & dp_{i,2} & \dots & dp_{i,|S|} \end{pmatrix} = \begin{pmatrix} dp_{i-1,1} & dp_{i-1,2} & \dots & dp_{i-1,|S|} \end{pmatrix} \begin{pmatrix} check(S_1,S_1) & check(S_1,S_2) & \dots & check(S_1,S_{|S|}) \\ check(S_2,S_1) & check(S_2,S_2) & \dots & check(S_2,S_{|S|}) \\ \dots & \dots & \dots & \dots\\ check(S_{|S|},S_1) & check(S_{|S|},S_2) & \dots & check(S_{|S|},S_{|S|}) \\ \end{pmatrix} \]

这样,我们答案就为:

\[\begin{pmatrix} 1 & 1 & \dots & 1 \end{pmatrix} \begin{pmatrix} check(S_1,S_1) & check(S_1,S_2) & \dots & check(S_1,S_{|S|}) \\ check(S_2,S_1) & check(S_2,S_2) & \dots & check(S_2,S_{|S|}) \\ \dots & \dots & \dots & \dots\\ check(S_{|S|},S_1) & check(S_{|S|},S_2) & \dots & check(S_{|S|},S_{|S|}) \\ \end{pmatrix}^{n-1} \]

配合矩阵快速幂求解,时间复杂度:\(O(8^m\log n)\)

第五步,小细节。对于取模,由于模数为 \(2^{32}\),只需用 \(\text{unsigned}\) \(\text{int}\) 自然溢出即可。

Code

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef unsigned int ui;
const int N=1e6+10;
int n,m,p,k,a[4],x,S[74],cnt;
ui Ans;
struct mat {ui a[74][74];int r,c;mat() {memset(a,0,sizeof(a));}
};
mat operator * (mat x,mat y) {mat z;z.r=x.r,z.c=y.c;for(int i=1;i<=x.r;i++)for(int j=1;j<=y.c;j++)for(int k=1;k<=x.c;k++)z.a[i][j]=z.a[i][j]+x.a[i][k]*y.a[k][j];return z;
}
mat ksm(mat x,int y) {mat ret=x;y--;while(y) {if(y&1) ret=ret*x;x=x*x;y>>=1;}return ret;
}
mat G,sta,ans;
bool check1(int u) {for(int i=1;i<=m;i++) {if((u>>(i-1))&1) {if(i-k<0) {if(u&(a[2]>>(k-i))) return false;}else {if(u&(a[2]<<(i-k))) return false;}}} return true;
}
bool check2(int u,int v) {for(int i=1;i<=m;i++) {if((u>>(i-1))&1) {if(i-k<0) {if(v&(a[3]>>(k-i))) return false;}else {if(v&(a[3]<<(i-k))) return false;}}} for(int i=1;i<=m;i++) {if((v>>(i-1))&1) {if(i-k<0) {if(u&(a[1]>>(k-i))) return false;}else {if(u&(a[1]<<(i-k))) return false;}}} return true;
}
signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>n>>m>>p>>k;k++;for(int i=1;i<=3;i++) {for(int j=1;j<=p;j++) {cin>>x;if(i==2&&j==k) x=0;a[i]|=(x<<(j-1)); }} for(int i=0;i<(1<<m);i++) if(check1(i)) S[++cnt]=i;sta.r=1,sta.c=cnt;G.r=G.c=cnt;for(int i=1;i<=cnt;i++) {sta.a[1][i]=1;for(int j=1;j<=cnt;j++)if(check2(S[i],S[j])) G.a[i][j]=1;}ans=sta*ksm(G,n-1);for(int i=1;i<=cnt;i++) Ans+=ans.a[1][i];cout<<Ans;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/924320.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

申请建设门户网站的申请电子商务网站建设 试卷

前言 中篇讲了进程为什么要有优先级&#xff0c;以及环境变量和通过代码获得环境变量 本篇主要讲解什么是地址空间 &#xff0c; 地址空间是怎么设计的&#xff1f;为什么要有地址空间&#xff1f; 程序地址空间 先看下图 验证上图的正文代码至堆的地址是不是从低地址向高地…

VMware vCenter Server 7.0U3w 发布 - 集中管理 vSphere 环境

VMware vCenter Server 7.0U3w 发布 - 集中管理 vSphere 环境VMware vCenter Server 7.0U3w 发布 - 集中管理 vSphere 环境 Server Management Software | vCenter 请访问原文链接:https://sysin.org/blog/vmware-vce…

VMware Aria Operations 8.18.5 发布,新增功能概览

VMware Aria Operations 8.18.5 发布,新增功能概览VMware Aria Operations 8.18.5 发布,新增功能概览 VMware Aria Operations 8.18.5 - 多云 IT 运维管理 通过统一的高性能平台,实现跨私有云、混合云和多云环境的 …

03. 基本元素

一、基本元素元素可以被分为 可视化元素 与 非可视化元素。一个 可视化元素(例如矩形框 Rectangle)有着几何形状并且可以在屏幕上显示。一个 非可视化元素(例如计时器 Timer)提供了常用的功能,通常用于操作可视化…

VMware Aria Operations for Logs 8.18.5 发布,新增功能概览

VMware Aria Operations for Logs 8.18.5 发布,新增功能概览VMware Aria Operations for Logs 8.18.5 发布,新增功能概览 VMware Aria Operations for Logs 8.18.5 - 集中式日志管理 请访问原文链接:https://sysin.…

学做川菜的网站黑龙省建设厅网站首页

文章目录 1、DES中的S-盒输入输出问题 &#xff08;不需要记住S-盒&#xff09;2、Kerberos认证系统3、简答题&#xff08;三题每题8分&#xff09;&#xff1a;课后习题第一章、第三章、第四章第一章&#xff1a;重点关注安全模型内容&#xff0c;有几种&#xff0c;有几个分级…

喵之勇者败北录

⚡毕竟😣D/N/A🧬😱无法诉说😍⚡⚡这颗心🥰😭在我心中🧬浸染成红❤️浸染成红🖤⚡⚡睡不着啊😱没有迷路的东西🧬😍不是请求😭💧⚡这个细胞是🧬🥰愛憎😣被刻上了⚡⚡还没找到😭🧬还…

中南路网站建设公司代理财务记账公司

一、什么是Sass Sass (Syntactically Awesome StyleSheets)是css的一个扩展开发工具&#xff0c;它允许你使用变量、条件语句等&#xff0c;使开发更简单可维护。这里是官方文档。 二、基本语法 1&#xff09;变量 sass的变量名必须是一个$符号开头&#xff0c;后面紧跟变量名…

岳西县建设局网站电子书制作公司网站

本文为大家揭示 NebulaGraph 率先提出的 Graph RAG 方法&#xff0c;这种结合知识图谱、图数据库作为大模型结合私有知识系统的最新技术栈&#xff0c;是 LLM 系列的第三篇&#xff0c;加上之前的图上下文学习、Text2Cypher 这两篇文章&#xff0c;目前 NebulaGraph LLM 相关的…

【完整源码+素材集+部署教程】鱼类部位分割系统: yolov8-seg-goldyolo

【完整源码+素材集+部署教程】鱼类部位分割系统: yolov8-seg-goldyolopre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: &…

Windows 作为 Ansible 节点的完整部署流程(含 Docker 部署 Ansible) - 实践

Windows 作为 Ansible 节点的完整部署流程(含 Docker 部署 Ansible) - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fam…

软工

这个作业属于哪个课程 <班级的链接>这个作业的目标 <你理解的作业目标具体内容>姓名-学号 <你的姓名>-<你的学号>

帮做装修设计的网站建设工程消防备案凭证网站

【工具使用】adb下载和配置 一&#xff0c;简介二&#xff0c;操作步骤2.1 Bing搜索adb2.2 下载adb工具2.3 添加路径到环境变量 三&#xff0c;效果验证 一&#xff0c;简介 本文主要介绍如何下载adb并安装使用&#xff0c;供参考。 此时打开cmd&#xff0c;输入adb 会提示&am…

湖北可以做网站的公司淄博网站外包

!! http://www.shoudian.org/thread-316111-1-1.html http://www.jiequer.com/html/news/xinpin/2014/1218/223.html http://bbs.mydigit.cn/read.php?tid930053转载于:https://www.cnblogs.com/carl2380/p/5239022.html

简单个人博客模板网站wordpress 36氪主题

物理引擎概念解释 所谓物理引擎,就是通过代码模拟物理世界。举个简单例子,比如你初高中都学过物理学,其中力、速度、加速度、位移都是比较常见的物理量,咱们通过CannonJS等物理引擎,都可以辅助你计算生活中物体的速度、位移,比如计算一个小球在地球重力的作用下,下落的…

滕州网站建设 助企网络集团门户网站建设方案 php

OK&#xff0c;那么上篇博客我们介绍了如何搭建基于Javaselenium的环境&#xff0c;并且使用selenium的一些语法给大家演示了如何进行自动化测试的案例&#xff0c;那么本篇博客我们来继续学习selenium的一些其他的比较重要的语法&#xff0c;感谢关注&#xff0c;期待三连~ 目…

10.1考试T4(swap)题解

题目描述 \(link\) 小 D 正在研究交换。 小 D 认为一个整数序列是好的,当且仅当它先(不严格)上升,后(不严格)下降。 形式化地,我们认为序列 \(𝑎_1,𝑎_2,...,𝑎_𝑛\) 是好的,当且仅当存在某个 \(𝑘∈…

如何在windows10的子系统(wsl)中安装php开发环境 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

学校网站建设经验介绍网络营销策划名词解释

Hi~ 大家好久不见呀&#xff01; 一直忙&#xff0c;但不知道在忙啥&#xff0c;好多事情都落下了&#xff0c;ERP的文章最近也没有时间更新&#xff0c;接下去我还在考虑弄个直播&#xff0c;不知道大家有没有什么想了解的&#xff0c;大家给我留言&#xff0c;直播的时候给…

抚顺网站开发3g微网站

当从键盘连续进行输入时用while&#xff0c;但是程序自己不会通过正常的输入结束。 scanf("%d%d",&a, &b); 如果a和b都被成功读入&#xff0c;scanf()的返回值是2 如果只有a被成功读入或者只有b被成功读入&#xff0c;scanf()的返回值为1 如果a和b都未被…