NOIP2023模拟10联测31 涂鸦

news2024/12/25 15:18:54

题目大意

有一面由 n × m n\times m n×m个格子组成的墙,每个格子要么是黑色,要么是白色。你每次将会进行这样的操作:等概率随机选择一个位置 ( x , y ) (x,y) (x,y)和一个颜色 c c c(黑色或白色),( 1 ≤ x ≤ n , 1 ≤ y ≤ m 1\leq x\leq n,1\leq y\leq m 1xn,1ym,选择任意 ( x , y , c ) (x,y,c) (x,y,c)的组合的概率都是 1 2 n m \dfrac{1}{2nm} 2nm1),然后将 ( x , y ) (x,y) (x,y)左上角的所有格子的颜色都涂成 c c c,也就是将所有满足 1 ≤ x ′ ≤ x , 1 ≤ y ′ ≤ y 1\leq x'\leq x,1\leq y'\leq y 1xx,1yy的格子 ( x ′ , y ′ ) (x',y') (x,y)的颜色涂成 c c c。次操作的代价为涂的格子的数量,即 x × y x\times y x×y。给定初始状态和终止状态,问期望要花费多少代价才能将墙面从初始状态涂成终止状态。

1 ≤ n , m ≤ 5 1\leq n,m\leq 5 1n,m5


题解

看到 n n n m m m都比较小,我们考虑用状压 D P DP DP。设 f s f_s fs表示当前墙面的状态为 s s s时要到最终状态的期望代价,可以列出 2 n m 2^{nm} 2nm个方程,用高斯消元解方程即可。

这样做的时间复杂度为 O ( 2 3 n m ) O(2^{3nm}) O(23nm),我们考虑优化。

我们考虑减少状态的数量。我们发现,如果一个位置的右下角的某个位置与最终状态不同,则这个位置一定会被修改,那这个位置当前的值就不重要了。

p i , j p_{i,j} pi,j表示 ( i , j ) (i,j) (i,j)右下角的位置是否已经全部变得和终止状态一样,可以发现 p i , j p_{i,j} pi,j 1 1 1的状态一定在右下角呈阶梯状的。举个例子:

在这里插入图片描述
其中橙色部分为 p i , j = 1 p_{i,j}=1 pi,j=1的格子。

那么,总状态数为 ( n + m n ) \binom{n+m}{n} (nn+m)。我们可以用 d f s dfs dfs求出所有可能的状态。

对于每个状态,我们考虑它能到达哪些状态。我们将每种状态中 p i , j = 1 p_{i,j}=1 pi,j=1的格子设为与终止状态相同, p i , j = 0 p_{i,j}=0 pi,j=0的格子设为与终止状态相反。然后将左上角的一个矩形全部变为黑色或白色,再判断改变颜色后的状态是什么状态。

用上述方法求出转移方程,再用高斯消元求解即可。

时间复杂度为 O ( ( n + m n ) 3 ) O(\binom{n+m}{n}^3) O((nn+m)3) ( n + m n ) \binom{n+m}{n} (nn+m)的最大值为 252 252 252,是可以过的。

code

#include<bits/stdc++.h>
using namespace std;
const long long mod=998244353;
int n,m,S,bg=0,ed=0,sum=0,tot=0,w[10][10];
long long ans=0,a[305][305];
char s[10][10],t[10][10];
array<int,5>v;
map<array<int,5>,int>mp;
void init(){
	S=(1<<n*m)-1;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			for(int x=0;x<=i;x++){
				for(int y=0;y<=j;y++){
					w[i][j]|=1<<(x*m+y);
				}
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			sum+=2*i*j;
		}
	}
}
void dfs(int t,int now){
	if(t==n){
		mp[v]=++tot;
		return;
	}
	for(int i=now;i<=m;i++){
		v[t]=i;dfs(t+1,i);
	}
}
int gtid(int s){
	array<int,5>b;
	for(int i=0;i<5;i++) b[i]=0;
	for(int i=0;i<n;i++){
		b[i]=m;
		for(int j=0;j<m;j++){
			int wt=(s>>(i*m+j))&1;
			if(wt==(t[i][j]=='W')) b[i]=m-j-1;
		}
	}
	for(int i=n-2;i>=0;i--) b[i]=min(b[i],b[i+1]);
	return mp[b];
}
long long mi(long long t,long long v){
	if(!v) return 1;
	long long re=mi(t,v/2);
	re=re*re%mod;
	if(v&1) re=re*t%mod;
	return re;
}
void gauss(){
	for(int i=1;i<=tot;i++){
		for(int j=i;j<=tot;j++){
			if(a[j][i]){
				swap(a[j],a[i]);break;
			}
		}
		for(int j=1;j<=tot;j++){
			if(i==j) continue;
			long long dv=(mod-1)*a[j][i]%mod*mi(a[i][i],mod-2)%mod;
			for(int k=1;k<=tot+1;k++) a[j][k]=(a[j][k]+dv*a[i][k])%mod;
		}
	}
}
int main()
{
//	freopen("graffiti.in","r",stdin);
//	freopen("graffiti.out","w",stdout);
	scanf("%d%d",&n,&m);
	init();
	for(int i=0;i<n;i++) scanf("%s",s[i]);
	for(int i=0;i<n;i++) scanf("%s",t[i]);
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			bg|=(s[i][j]=='B')<<(i*m+j);
			ed|=(t[i][j]=='B')<<(i*m+j);
		}
	}
	dfs(0,0);
	for(auto p:mp){
		int s=0,id=p.second;
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(j<m-p.first[i])
				s|=(t[i][j]=='W')<<(i*m+j);
				else
				s|=(t[i][j]=='B')<<(i*m+j);
			}
		}
		a[id][id]=2*n*m;
		if(s==ed) continue;
		a[id][tot+1]=sum;
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				int tmp=gtid(s|w[i][j]);
				a[id][tmp]=(a[id][tmp]-1+mod)%mod;
				tmp=gtid(s&(S^w[i][j]));
				a[id][tmp]=(a[id][tmp]-1+mod)%mod;
			}
		}
	}
	gauss();
	int tmp=gtid(bg);
	ans=a[tmp][tot+1]*mi(a[tmp][tmp],mod-2)%mod;
	printf("%lld",ans);
	return 0;
}

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

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

相关文章

Portraiture4.1.2最新中文汉化版

提起PS后期修图人像美白磨皮&#xff0c;大家会想到各种磨皮工具&#xff0c;其中Portraiture这款磨皮效率超高&#xff0c;是99%摄影师的必备插件&#xff0c;一秒磨皮&#xff0c;无卡顿&#xff0c;效果好&#xff01;人像摄影师人均一款&#xff0c;磨皮质感非常好&#xf…

ER图:改变你数据库设计流程的神器!

在现今数据驱动的世界中&#xff0c;数据库设计扮演了至关重要的角色。为了实现有效且准确的数据存储和检索&#xff0c;企业们开始倾向于采用实体关系图&#xff08;Entity-Relationship Diagram&#xff0c;简称ER图&#xff09;来优化他们的数据库设计流程。本文将带你走进E…

Rust编程基础之条件表达式和循环

1.if表达式 if 表达式允许根据条件执行不同的代码分支, 以下代码是一个典型的使用if表达式的例子: fn main() {let number 3; ​if number < 5 {println!("condition was true");} else {println!("condition was false");} } 所有的 if 表达式都以…

win10 + vs2017 + cmake3.17编译OSG-3.4.1

参考教程&#xff1a;https://blog.csdn.net/bailang_zhizun/article/details/120992244 1. 下载与解压 2. 修改configure 1&#xff09;Ungrouped Entries -- 》ACTUAL_3RDPARTY_DIR: 设置为&#xff1a; D:/Depend_3rd_party/OSG341/3rdParty 2&#xff09; Ungrouped E…

免费的 AI 视频生成工具 Moonvalley 厉害了!Moonvalley 怎么用(保姆级教程)

一、Moonvalley 介绍 Moonvalley&#xff0c;号称地表最强的 AI 视频生成工具&#xff0c;到底有多厉害&#xff1f;今天一起来看一下~ 这是 Moonvalley 官网的介绍&#xff1a; Moonvalley 是一个开创性的新型文本到视频的生成式 AI 模型。用简单的文本即可创建出惊人的电影和…

分享一个自己写的免费的微信聊天记录提取软件 2023.11.03

有什么办法可以导出与某个人的微信聊天记录&#xff1f; 只想导出与某个微信好友的聊天记录&#xff0c;有办法做到吗&#xff1f;导出所有的话&#xff0c;文件太大了&#xff0c;只想导出与其中一个人的&#xff0c;求大神教。 我的需求和上面这个人的比较类似&#xff0c;因…

2023辽宁省数学建模竞赛选题建议及AB题思路

大家好呀&#xff0c;今天早上2023年辽宁省大学生数学建模竞赛开赛&#xff0c;在这里给大家带来初步的选题建议及思路。 注意&#xff0c;本文只是比较简略的图文版讲解&#xff0c;完整的视频版讲解请移步&#xff1a; 2023辽宁省数学建模竞赛选题建议及初步思路_哔哩哔哩_…

【面经】讲一下synchronized锁升级的过程

synchronized锁升级是指从偏向锁到轻量级锁&#xff0c;再到重量级锁的过程。 当线程获取synchronized对象时&#xff0c;首先会进行偏向锁的尝试。 如果偏向锁没有竞争&#xff0c;线程将永远不需要同步。 但是&#xff0c;如果偏向锁竞争失败&#xff0c;将升级到轻量级锁。…

python自动化测试模板

1:准备html模版 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>接口自动化…

数据库管理-第114期 Exadata 05-ESS-上(202301103)

数据库管理-第114期 Exadata 05-ESS-上&#xff08;202301103&#xff09; 之前提到过&#xff0c;Exadata通过ESS将存储转换为了智能存储&#xff0c;其实相较于纸面参数非常牛逼但性能还是比不过Exadata的国产一体机&#xff0c;最大的差距也就是在ESS上&#xff0c;从数据库…

自动化测试如何准备测试数据

其实大部分类型的测试都需要去准备测试数据。 手工测试&#xff1a;一些基础数据&#xff0c;比如配置数据等等是需要去准备的&#xff1b;自动化测试&#xff1a;基础需要准备&#xff0c;现有数据&#xff0c;动态运行时产生的数据是需要准备的&#xff1b;性能测试&#xf…

华为云API Explorer伙伴招募火热进行中~

API编排新特性助力伙伴 零代码构建API工作流 实现快速集成场景编排能力 面向三大核心场景&#xff1a; API调用逻辑频繁改动 API间高耦合不便管理 复杂API解决方案难构建 伙伴加入可立享四大限时福利&#xff1a; 免费试用、专家咨询、技术指导、生态支持 点此报名>&…

XSpirit 2智能边缘计算机使用测评

博客主页&#xff1a;https://tomcat.blog.csdn.net 博主昵称&#xff1a;农民工老王 主要领域&#xff1a;Java、Linux、K8S 期待大家的关注&#x1f496;点赞&#x1f44d;收藏⭐留言&#x1f4ac; 目录 拆箱过程介绍视频使用感受 我之前就参加过 Spirit 1 第一代智能边缘计…

Web自动化测试 —— PageObject设计模式!

一、page object 模式简介 1.1、传统 UI 自动化的问题 无法适应 UI 频繁变化无法清晰表达业务用例场景大量的样板代码 driver/find/click 二、page object 设计原则 2.1、POM 模式的优势 降低 UI 变化导致的测试用例脆弱性问题让用例清晰明朗&#xff0c;与具体实现无关 2.…

人工智能AI创作系统ChatGPT网站系统源码+AI绘画系统支持GPT4.0/支持Midjourney局部重绘

一、前言 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建…

压缩软件 7-Zip VS WinZips

7-zip在联想应用商店给强烈推荐&#xff1f; 要说它好用还行&#xff0c;但每次压缩都显示网络连接失败等异常广告信息。 相反好用的7-ZIP必须鼠标点击右键点击更多才能够看到&#xff0c;这次更新体验也太差了吧&#xff1f; 用户放在第一位&#xff1f; 要不是更新后一直推…

【技术分享】RK356X Android 使用 libgpiod 测试gpio

前言 libgpiod 是用于与 Linux GPIO 字符设备交互的 C 库和工具库&#xff1b;此项目包含六种命令行工具&#xff08;gpiodetect、gpioinfo、gpioset、gpioget、gpiomon&#xff09;&#xff0c;使用这些工具可以在命令行设置和获取GPIO的状态信息&#xff1b;在程序开发中也可…

Python库学习(十二):数据分析Pandas[下篇]

接着上篇《Python库学习(十一):数据分析Pandas[上篇]》,继续学习Pandas 1.数据过滤 在数据处理中&#xff0c;我们经常会对数据进行过滤&#xff0c;为此Pandas中提供mask()和where()两个函数&#xff1b; mask(): 在 满足条件的情况下替换数据&#xff0c;而不满足条件的部分…

BUUCTF 另外一个世界 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 下载附件&#xff0c;解压得到一个.jpg图片。 密文&#xff1a; 解题思路&#xff1a; 1、这道题我尝试了很多方法&#xff0c;知道看了别人的wp才知道flag在我忽略的地方。将图片在010 Editor中打开&#xff0c;从…

Redis学习系统(持续更新中)

RedisExample 课程介绍 目标是提供一个高效、可靠的学习和实践Redis的环境。我们将通过搭建Redis集群、实现缓存数据的持久化存储、制定缓存数据的淘汰策略以及同步缓存数据等步骤来深入了解和学习Redis的特性和功能。通过这个项目&#xff0c;你可以掌握Redis的核心概念和技…