首页 > 其他分享 >状压DP

状压DP

时间:2022-10-13 15:37:05浏览次数:48  
标签:ch Genotype int 状压 NIE 分裂 规则 DP

[POI1997] Genotype

题目背景

Genotype 是一个独特的基因串。

题目描述

我们可以用大写英文字母 $A-Z$ 来描述 Genotype,每个字母就代表一个基因。

规定一种「分裂」规则,由三个大写字母 $A_1A_2A_3$ 组成,代表 $A_1$ 可以「分裂」为 $A_2A_3$。

现在给定 $n$ 个「分裂」规则和 $k$ 个 Genotype,判断这些 Genotype 是否能从一个特定的 只包含大写字母 $S$ 的 串通过「分裂」规则得到,如果可以的话输出特定的串的长度的最小值,如果不可以的话输出 NIE

输入格式

第一行一个整数 $n$ 代表「分裂」规则数。
接下来 $n$ 行每行三个大写字母 $A_1,A_2,A_3$ 代表一个「分裂」规则。
接下来一行一个整数 $k$ 代表给定的 Genotype 数。
接下来 $k$ 行每行若干个大写字母表示一个 Genotype。

输出格式

$k$ 行:

  • 如果没有特定的串通过「分裂」规则得到这个 Genotype,输出 NIE
  • 如果有特定的串通过「分裂」规则得到这个 Genotype,输出这个特定的串的最小长度。

样例 #1

样例输入 #1

6
SAB
SBC
SAA
ACA
BCC
CBC
3
ABBCAAABCA
CCC
BA

样例输出 #1

3
1
NIE

提示

数据规模与约定

对于 $100%$ 的数据,$1 \le n,k \le 2000$,Genotype 的长度最大为 $100$。


#include<bits/stdc++.h>
using namespace std;
const int N=333;
int n,k;
int book[27][27],dv[N][N],f[N][N];//divide
//book[N][N]:两个字母能合并成一个字母 (规则) 
//dv[N][N]:两个区间都能合并成哪个字母  
//f[N][N]此区间能变成此S的区间的个数
//目标:把序列都变成S且S的数量最少 
char a[N];
int main()
{
	scanf("%d",&n);
	for(int i = 1;i <= n;i++)
	{
		char ch;
		cin>>ch;
		int x = ch-'A'+1;
		cin>>ch;
		int y = ch-'A'+1;
		cin>>ch;
		int z = ch-'A'+1;
		book[y][z] |= 1 << x;
	}
	
	scanf("%d",&k);
	while(k--)
	{
		memset(dv,0,sizeof(dv));
		memset(f,0x3f,sizeof(f));
		
		scanf("%s",a+1);
		int le=strlen(a+1);
		
		for(int i = 1;i <= le;i++)
		{
			if(a[i] == 'S') f[i][i]=1;//能成S即为一 
			dv[i][i] |= (1<<(a[i]-'A'+1));//一个字母可以不变就是它自己 
		}
		
		for(int len = 1;len <= le;len++)
			for(int l = 1;l + len-1 <= le;l++)
			{
				int r=l+len-1;
				for(int k = l;k < r;k++)
				{
					f[l][r] = min(f[l][r],f[l][k] + f[k+1][r]);//取变成S最少的两个小区间
					for(int x = 1;x <= 26;x++)
						for(int y = 1;y <= 26;y++) 
							if((dv[l][k]&(1<<(x))) && (dv[k+1][r]&(1<<(y))))//两个小区间能变成的字母两两组合成新的字母继承给大区间 
								dv[l][r] |= book[x][y];
				}
				if(dv[l][r]&(1<<('S'-'A'+1))) f[l][r]=1;//整个区间能变成一个S 就直接等于一因为要最少 
			}
		
		if(f[1][le] >= 0x3f3f3f3f) printf("NIE\n");
		else printf("%d\n",f[1][le]);
	}
}

标签:ch,Genotype,int,状压,NIE,分裂,规则,DP
From: https://www.cnblogs.com/AC7-/p/16788274.html

相关文章

  • xrdp 启动分析
    一、在初次启动xrdp服务sudosystemctlrestartxrdp1、xrdp[20221013-14:10:56][INFO]startingxrdpwithpid23602./xrdp/xrd......
  • 【STM32H7】第14章 UDP用户数据报协议基础知识
    ​​​​第14章      UDP用户数据报协议基础知识本章节为大家讲解UDP(UserDatagramProtocol,用户数据报协议),需要大家对UDP有个基础的认识,方便后面章节UDP实战操作。(......
  • ThreadPool ExecutorService使用invokeAll提交多个任务并等待结果返回
    https://blog.csdn.net/liangwenmail/article/details/79421029  invokeAll可以提交多个任务,在任务完成前该方法会阻塞,直到所有任务完成或中断或超时,返回Future列表。......
  • 关于一个人类智慧的DP - Vijos 1037 搭建双塔 题解
    关于一个人类智慧的DP-Vijos1037搭建双塔目录关于一个人类智慧的DP-Vijos1037搭建双塔更好的阅读体验戳此进入题面输入格式ExamplesSolutionCodeCode-C++98(JDO......
  • 【高并发】ScheduledThreadPoolExecutor与Timer的区别和简单示例
    JDK1.5开始提供ScheduledThreadPoolExecutor类,ScheduledThreadPoolExecutor类继承ThreadPoolExecutor类重用线程池实现了任务的周期性调度功能。在JDK1.5之前,实现任务的......
  • oracle 21c expdp报错误UDE-31623
     环境:OS:Centos7DB:21C 导出报错expdpc##goldengate/goldengate@tnspdb1tables=hxl.tb_testdumpfile=tb_test.dmpFLASHBACK_SCN=4990304parallel=5direct......
  • Luogu2167 Bill的挑战 - 容斥 - dp -
    题目链接:https://www.luogu.com.cn/problem/P2167题解:摘录一段描述容斥题目的话:本题中,关于容斥系数,可以先感性理解一下,严格证明可以用即除了自身,自身的超集都计算......
  • dp 记录
    感觉自己dp不行,打算先专门练一阵子dp。以下是从国庆开始的训练实录。会根据我自己水平定个难度。\(\rmEasy\):独立想出并用时短。\(\rmMiddle\):独立想出并用时长......
  • wordpress 开发相关函数
    首页判断is_home()is_front_page()当你的首页不是默认的index.php的时候,而是在后台指定了一个page页面。这种情况下is_home()会失效,也就是说这样子的情况下就不能再用is......
  • 【洛谷】P8256 [NOI Online 2022 入门组] 字符串(dp)
    原题链接题意给定两个由0,1,-组成的字符串\(S\),\(T\),以及一个空串\(R\)。\(S\)的长度为\(n\)。现在要进行\(n\)次操作,每一次操作取出\(S\)的第一个字符\(c\)......