首页 > 其他分享 >P4290 [HAOI2008] 玩具取名(区间dp,传递闭包?)

P4290 [HAOI2008] 玩具取名(区间dp,传递闭包?)

时间:2024-08-15 20:49:07浏览次数:8  
标签:闭包 字符 mat int re 区间 P4290 对应 dp

link

有点传递闭包的思想感觉这题(无聊倒装

首先为了便于处理,将 W,I,N,G 映射为 1,2,3,4

那么处理数据,想到可以用 传递闭包 的思想?感觉差不多,因为这道题有很多一一对应的关系

对于每次输入对应的两个字符 \(ab\),定义 \(g[a, b, i]\in\{0,1\}\) 表示对应关系


题目要求给定一个串 \(s\) 和一些对应关系,最终可以转化为哪几个单个字符,相当于我们知道单个字符的对应双字符,然后看看能不能对应上整个 \(s\),从小区间推到大区间,考虑 区间dp

定义 \(f[l, r, x]\in\{0,1\},~x\in\{1,2,3,4\}\) 表示区间 \([l, r]\) 是否可以被“字符”\(x\) 替换掉,也就是对应上

引入中间值 \(k\),将区间分而治之拆分成 \(f[l,k,?]\) 和 \(f[k + 1, r, ?]\)

两个小区间的第三维度?想到 一个字符总是对应两个字符,所以另外两个字符也要分别枚举,不过要能转移的条件肯定要 另外两个字符能对应 \(x\),即:

\[f[l,r,x] = f[l,r,x]~|~(f[l,k,y] ~\&~ f[k+1,r,z]~\&~ g[y,z,x]) \]

哦对了,注意边界初始化,对于区间 [i, i],它肯定能被 i 上的字符替换

忽略枚举 \(x,y,z\) 的常数,还是 \(O(n^3)\)

#include <bits/stdc++.h>
#define re register int 

using namespace std;
const int N = 210;

int n, s[5], mat[N];
int g[5][5][5], f[N][N][5];
char t[N];

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	
	mat['W'] = 1, mat['I'] = 2, mat['N'] = 3, mat['G'] = 4;
	
	for (re i = 1; i <= 4; i ++) cin >> s[i];
	for (re i = 1; i <= 4; i ++)
		for (re j = 1; j <= s[i]; j ++)
		{
			string c; cin >> c;
			g[mat[c[0]]][mat[c[1]]][i] = 1;
		}
	string tt; cin >> tt;
	n = tt.size();
	for (re i = 0; i < n; i ++) t[i + 1] = tt[i];
	
	for (re i = 1; i <= n; i ++) f[i][i][mat[t[i]]] = 1;
	for (re len = 1; len <= n; len ++)
		for (re l = 1; l + len - 1 <= n; l ++)
		{
			int r = l + len - 1;
			for (re k = l; k < r; k ++)
				for (re x = 1; x <= 4; x ++)
					for (re y = 1; y <= 4; y ++)
						for (re z = 1; z <= 4; z ++)
							f[l][r][x] = f[l][r][x] | (f[l][k][y] & f[k + 1][r][z] & g[y][z][x]);
		}
	
	bool flag = false;
	if (f[1][n][1]) { flag = true; cout << 'W'; }
	if (f[1][n][2]) { flag = true; cout << 'I'; }
	if (f[1][n][3]) { flag = true; cout << 'N'; }
	if (f[1][n][4]) { flag = true; cout << 'G'; }
	if (!flag) cout << "The name is wrong!";
	cout << '\n';
	
	return 0;
}

标签:闭包,字符,mat,int,re,区间,P4290,对应,dp
From: https://www.cnblogs.com/wenzieee/p/18361789

相关文章

  • 初识DPDK
    DPDK是dataplanedevelopmekit的缩写,是一个c语言编写的软件开发框架,常用于高性能网络的开发。它的主要功能就是让用户绕过linux内核协议栈,将网卡收到的数据包直接在用户态空间内使用用户自定义的逻辑去处理数据包,或者将用户态空间的数据包绕过一系列的内核协议栈封装直接从网卡......
  • 2024.8.14 DP Round 2
    A.storeStatement:有\(n(1\len\le100)\)个果盘,其中第\(i\)个果盘有\(a_i\)个水果,容量是\(b_i(a_i\leb_i\le100)\)。一次操作可以将一个水果从一个果盘放到另一个果盘中,现在要将所有水果放到最少的盘子中,问最少要用多少盘子以及最少需要多少操作。Solution:第一......
  • 亮相2024 DPU&AI Networking创新大会,天翼云斩获两项大奖!
    近日,以“智驱网络芯动未来”为主题的2024DPU&AINetworking创新大会在北京举办。大会表彰了在DPU与AI网络技术创新及实践应用中取得卓越成就的单位与项目,天翼云科技有限公司荣膺创新引擎奖、《紫金DPU算力卸载与网络加速应用》荣获实践先锋奖,技术创新实力以及应用实践成果再获行......
  • golang gin框架中创建自定义中间件的2种方式总结 - func(*gin.Context)方式和闭包函数
    在gin框架中,我们可以通过2种方式创建自定义中间件:1.直接定义一个类型为 func(*gin.Context)的函数或者方法    这种方式是我们常用的方式,也就是定义一个参数为*gin.Context的函数或者方法。定义的方法就是创建一个参数类型为gin.HandlerFunc【他的原型定义为t......
  • udp和arp之间的交互作用
    udp和arp之间的交互作用arp-a验证arp告诉缓存是空的sock-u-i-nl-w8192svr4discard1.在第一个arp应答返回以前,总共产生了6个arp请求。2.在接收到第一个arp应答时(第7行),只发送最后一个数据报片(第9行)3.在大多数的现实中,在等待一个arp应答时,只将最后一个报文发送给特定目标......
  • udp介绍
    1.udp介绍udp是一个简单的面向数据报的运输层协议,进程的每个输出操作都正好产生一个udp数据报,并组装成一份待发送的ip数据包,这与面向流字符的协议不同,如tcp,应用程序产生的全体数据与真正发送的单个ip数据报可能没有什么联系。udp不提供可靠性:它把应用程序传给ip层的数据发送出......
  • 「Day 9 & 10—DP问题」
    DP问题定义什么是\(DP\),答曰:一种通过将全局问题分解成不同的子问题来进行对复杂问题的计算。在我看来就是一种递推的\(ProMax\)版,依旧是用之前计算过的来推出现在要计算的。DP板子问题P1115最大子段和思路我们用\(dp\)数组来定义到\(i\)为止,最大的子段和,那么我们......
  • Coin Troubles题解(dp,拓扑序)
    CoinTroubles题解(dp,拓扑序)题目链接:https://codeforces.com/problemset/problem/283/C题意:有\(n\)种硬币,每种硬币都有一个价格\(ai\),现在有\(q\)个限制,每个限制会告诉你\((b,c)\),并要求\(b\)种硬币的数量严格大于\(c\)种硬币的数量。现在问你一共有多少种买硬币的方法,使得最后......
  • 程序员面试题---------精细讲解DP协议编写网络程序以实现一个简单的加群和离群操作
    基于UDP协议编写网络程序以实现一个简单的加群和离群操作:假定:群组地址(224.0.2.100)服务器端地址为(192.168.14.44,具体根据主机指定)要求:1.加群的成员(客户端)加入一个群组后向管理者(服务器,地址公开)单播发送,“已加群”的消息,2.管理者(服务器每收到一个成员的加......
  • 0229-UDP 发送和接收
    环境Time2022-11-25WSL-Ubuntu22.04Rust1.65.0前言说明参考:https://doc.rust-lang.org/std/net/struct.UdpSocket.html目标之前通过接收整个IP和UDP报文来实现了通信,这里去除报文头的细节,直接通信。main.rsUDP由标准库直接支持,可以直接使用。将发送过来的信......