点头OJ 1033 . 骨牌覆盖 V2 ( 状态压缩 + 矩阵快速幂 )

2024-05-29 18:38

本文主要是介绍点头OJ 1033 . 骨牌覆盖 V2 ( 状态压缩 + 矩阵快速幂 ),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接~~>

做题感悟:先前做过一个类似的题,是俄罗斯的一道区域赛的题目,也是用的状态压缩 + 矩阵快速幂。

解题思路:状态压缩 + 矩阵快速幂

                构造一个矩阵 B [ i ] [ j ] 代表状态 i ,与状态 j 是否合法,j 代表上一行的状态,如果合法为 1 ,否则为 0 ,这样如果再得到初始各种状态的方案数的矩阵 A ,A 只有一列 ,这样 B * A 就是第二行各种状态对应 的方案数 。这样再加上矩阵快速幂就解决了。


代码:

#include<iostream>
#include<sstream>
#include<map>
#include<cmath>
#include<fstream>
#include<queue>
#include<vector>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<stack>
#include<bitset>
#include<ctime>
#include<string>
#include<cctype>
#include<iomanip>
#include<algorithm>
using namespace std  ;
#define INT long long int
#define L(x)  (x * 2)
#define R(x)  (x * 2 + 1)
const int INF = 0x3f3f3f3f ;
const double esp = 0.00000000001 ;
const double PI = acos(-1.0) ;
const INT mod = 1000000007 ;
const int MY = (1<<5) + 5 ;
const int MX = (1<<13) + 5 ;
const int S = 20 ;
int n ,m ;
INT key[50] ;
struct M
{INT p[32][32] ;M(){memset(p ,0 ,sizeof(p)) ;}void init(){for(int i = 0 ;i < (1<<m) ; ++i)p[i][i] = 1 ;}M operator *(const M& a){M c ;for(int i = 0 ;i < (1<<m) ; ++i)for(int k = 0 ;k < (1<<m) ; ++k)if(p[i][k])for(int j = 0 ;j < (1<<m) ; ++j)c.p[i][j] = (c.p[i][j] + p[i][k]*a.p[k][j])%mod ;return c ;}
};
M pow(M a ,int k)  // 矩阵快速幂
{M b ;b.init() ;while(k){if(k&1)  b = a * b ;a = a * a ;k >>= 1 ;}return b ;
}
void dfs(int S ,int cnt ,int tx ,int S1 ,M& c)
{if(cnt == m){c.p[S][tx] = 1 ;if(S1 == 0)   key[S] = 1 ;return ;}if(cnt + 2 <= m && !(S&(1<<cnt)) && !(S&(1<<(cnt+1))))dfs(S|(1<<cnt)|(1<<(cnt+1)) ,cnt+2 ,tx ,S1 ,c) ;dfs(S ,cnt+1 ,tx ,S1 ,c) ;
}
int main()
{//freopen("input.txt" ,"r" ,stdin) ;while(~scanf("%d%d" ,&n ,&m)){M c ;for(int i = 0 ;i < (1<<m) ; ++i)  // 处理各种对应的状态  同时初始化第一行的状态dfs((~i)&((1<<m)-1) ,0 ,i ,(~i)&((1<<m)-1) ,c) ;M b = pow(c ,n-1) ;INT ans = 0 ;for(int i = 0 ;i < (1<<m) ; ++i)ans = (ans + b.p[(1<<m)-1][i]*key[i])%mod ;cout<<ans%mod<<endl ;}return 0 ;
}






这篇关于点头OJ 1033 . 骨牌覆盖 V2 ( 状态压缩 + 矩阵快速幂 )的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1014328

相关文章

JWT + 拦截器实现无状态登录系统

《JWT+拦截器实现无状态登录系统》JWT(JSONWebToken)提供了一种无状态的解决方案:用户登录后,服务器返回一个Token,后续请求携带该Token即可完成身份验证,无需服务器存储会话... 目录✅ 引言 一、JWT 是什么? 二、技术选型 三、项目结构 四、核心代码实现4.1 添加依赖(pom

Python多线程实现大文件快速下载的代码实现

《Python多线程实现大文件快速下载的代码实现》在互联网时代,文件下载是日常操作之一,尤其是大文件,然而,网络条件不稳定或带宽有限时,下载速度会变得很慢,本文将介绍如何使用Python实现多线程下载... 目录引言一、多线程下载原理二、python实现多线程下载代码说明:三、实战案例四、注意事项五、总结引

C#使用Spire.XLS快速生成多表格Excel文件

《C#使用Spire.XLS快速生成多表格Excel文件》在日常开发中,我们经常需要将业务数据导出为结构清晰的Excel文件,本文将手把手教你使用Spire.XLS这个强大的.NET组件,只需几行C#... 目录一、Spire.XLS核心优势清单1.1 性能碾压:从3秒到0.5秒的质变1.2 批量操作的优雅

Mybatis-Plus 3.5.12 分页拦截器消失的问题及快速解决方法

《Mybatis-Plus3.5.12分页拦截器消失的问题及快速解决方法》作为Java开发者,我们都爱用Mybatis-Plus简化CRUD操作,尤其是它的分页功能,几行代码就能搞定复杂的分页查询... 目录一、问题场景:分页拦截器突然 “失踪”二、问题根源:依赖拆分惹的祸三、解决办法:添加扩展依赖四、分页

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

使用Redis快速实现共享Session登录的详细步骤

《使用Redis快速实现共享Session登录的详细步骤》在Web开发中,Session通常用于存储用户的会话信息,允许用户在多个页面之间保持登录状态,Redis是一个开源的高性能键值数据库,广泛用于... 目录前言实现原理:步骤:使用Redis实现共享Session登录1. 引入Redis依赖2. 配置R

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

使用zip4j实现Java中的ZIP文件加密压缩的操作方法

《使用zip4j实现Java中的ZIP文件加密压缩的操作方法》本文介绍如何通过Maven集成zip4j1.3.2库创建带密码保护的ZIP文件,涵盖依赖配置、代码示例及加密原理,确保数据安全性,感兴趣的... 目录1. zip4j库介绍和版本1.1 zip4j库概述1.2 zip4j的版本演变1.3 zip4

JAVA覆盖和重写的区别及说明

《JAVA覆盖和重写的区别及说明》非静态方法的覆盖即重写,具有多态性;静态方法无法被覆盖,但可被重写(仅通过类名调用),二者区别在于绑定时机与引用类型关联性... 目录Java覆盖和重写的区别经常听到两种话认真读完上面两份代码JAVA覆盖和重写的区别经常听到两种话1.覆盖=重写。2.静态方法可andro