Genotype&&陨石的秘密
Genotype:
Genotype 是一个有限的基因序列。它是由大写的英文字母A-Z组成,不同的字母表示不同种类的基因。一个基因可以分化成为一对新的基因。这种分化被一个定义的规则集合所控制。每个分化的规则可以用三个大写字母A1A2A3表示,含义为基因A1可以分化成A2A3
我们用S代表特种基因,繁殖genotype是从特种基因序列开始。根据给定的规则,它由被选择控制规则对基因不断进行繁殖而成。
任务
从文本文件GEN.IN 读入一个定义的规则集和一个想生成的genotypes 单词序列
对每一个给定的 genotype,根据给定的分化规则,检查是否它能从某一个确定特种基因序列生成,如果能,找到最小的序列长度,
将结果写入文本文件GEN.OUT.
输入
在文件GEN.IN 的第一行有一个整数n, 1 <= n <= 10000. 下面n 每一行为一个分化规则. 这些规则都由包含A – Z的三个大写字母组成.
接下来有一个整数k, 1 <= k <= 10000. 接下来的k 行有一个 genotype. Genotype由没有空格的单词组成,最多100 个英文大写字母.
输出
在文件GEN.OUT中有k行,在第I行应写入: 一个正整数――需要生成第I个genotypes的最小长度;或者单词 NIE, 如果不能生成对应的genotype。
--------------------------------------------------------------------
Ps.数据已弱化,可水过- =
读取时用一个map[A][B]数组表示 字母AB能变成的字母
由于只有26个字母,可以用一个26位的二进制数表示
进行两次动归
f[i][j]表示从字符串 从 i 到 j 能变成的字母,同理也是个二进制数
f[i][j]=f[i][j] |map[c1][c2] 存在 (f[i][k]&char[c1]&&f[k+1][j]&char[c2])
不难得到那几段字符串能变成 ‘S’
在进行一次动归
g[i]表示前 i 个字符能变成几个 ‘S’
g[i]=min(g[j]+1) 存在(f[i][j+1]&char['S'])
复杂度O(len^3*26^2)+O(len^2)
代码如下:
- #include<cstdio>
- #include<algorithm>
- #include<string>
- #include<cstring>
- #include<iostream>
- #include<cmath>
- #define LL long long
- #define INF 99999999
- #define Min(num1,num2) if(num1>num2) num1=num2
- #define Max(num1,num2) if(num1<num2) num1=num2
- using namespace std;
- int n,f[][],g[],num[],map[][];
- string s;
- void work(){
- memset(f,,sizeof f);
- cin>>s;
- int l=s.size();
- for(int k=,i=;i<l;k++,i++) f[k][k]=num[s[i]-'A'];
- for(int p=;p<=l;p++)
- for(int i=;i<=l;i++){
- int j=i+p;
- if(j>l) break;
- for(int k=i;k<j;k++)
- for(int ci=;ci<;ci++)
- for(int cj=;cj<;cj++)
- if((f[i][k]&num[ci])&&(f[k+][j]&num[cj]))
- f[i][j]|=map[ci][cj];
- }
- int key='S'-'A';
- for(int i=;i<=l;i++) g[i]=INF;
- g[]=;
- for(int i=;i<=l;i++)
- for(int j=;j<=i;j++)
- if((f[j][i]&num[key])&&g[j-]!=INF)
- Min(g[i],g[j-]+);
- g[l]==INF ? printf("NIE\n") : printf("%d\n",g[l]);
- }
- int main(){
- freopen("GEN.in","r",stdin);
- freopen("GEN.out","w",stdout);
- scanf("%d\n",&n);
- num[]=;
- for(int i=;i<=;i++) num[i]=num[i-]<<;
- for(int a,b,c,i=;i<=n;i++){
- a=getchar()-'A';
- b=getchar()-'A';
- c=getchar()-'A';
- map[b][c]|=num[a];
- getchar();
- }
- int T;
- scanf("%d\n",&T);
- while(T--) work();
- }
---------------------------------------------------------------------------
陨石的秘密:
公元11380年,一颗巨大的陨石坠落在南极。于是,灾难降临了,地球上出现了一系列反常的现象。当人们焦急万分的时候,一支中国科学家组成的南极考察队赶到了出事地点。经过一番侦察,科学家们发现陨石上刻有若干行密文,每一行都包含5个整数:
1 1 1 1 6
0 0 6 3 57
8 0 11 3 2845
著名的科学家SS发现,这些密文实际上是一种复杂运算的结果。为了便于大家理解这种运算,他定义了一种SS表达式:
1. SS表达式是仅由‘{’,‘}’,‘[’,‘]’,‘(’,‘)’组成的字符串。
2. 一个空串是SS表达式。
3. 如果A是SS表达式,且A中不含字符‘{’,‘}’,‘[’,‘]’,则(A)是SS表达式。
4. 如果A是SS表达式,且A中不含字符‘{’,‘}’,则[A]是SS表达式。
5. 如果A是SS表达式,则{A}是SS表达式。
6. 如果A和B都是SS表达式,则AB也是SS表达式。
例如
()(())[]
{()[()]}
{{[[(())]]}}
都是SS表达式。
而
()([])()
[()
不是SS表达式。
一个SS表达式E的深度D(E)定义如下:
例如(){()}[]的深度为2。
密文中的复杂运算是这样进行的:
设密文中每行前4个数依次为L1,L2,L3,D,求出所有深度为D,含有L1对{},L2对[],L3对()的SS串的个数,并用这个数对当前的年份11380求余数,这个余数就是密文中每行的第5个数,我们称之为“神秘数”。
密文中某些行的第五个数已经模糊不清,而这些数字正是揭开陨石秘密的钥匙。现在科学家们聘请你来计算这个神秘数。
输入文件
共一行,4个整数L1,L2,L3,D。相邻两个数之间用一个空格分隔。
(0≤L1≤10,0≤L2≤10,0≤L3≤10,0≤D≤30)
输出文件
共一行,包含一个整数,即神秘数。
---------------------------------------------------------------------------
Ps。坑爹数学题- =
题目所求在 l1个{} l2个[] l3个() 是有几个深度为 D 的 SS 串,
不妨设(g[l1][l2][l3][D])为使用 l1个{} l2个[] l3个() 时深度不超过 D 的 SS 串数目
题目所求就是 g[l1][l2][l3][D]-g[l1][l2][l3][D-1]
转移:
可以由以下集中状态转移过来:
(---------)-------------g[ 0 ][ 0 ][ i ][D-1]*g[l1 ][l2 ][l3-i-1]
[---------]-------------g[ 0 ][ j ][ i ][D-1]*g[l1 ][l2-j-1][l3-i ]
{--------}-------------g[ k ][ j ][ i ][D-1]*g[l1-k-1][l2-j ][l3-i ]
累加起来就是 g[l1][l2][l3][D]
Ps.边界 g[0][0][0][D]=0
代码如下:
- #include<cstdio>
- #include<algorithm>
- #include<string>
- #include<cstring>
- #include<iostream>
- #include<cmath>
- #define LL long long
- #define INF 999999999
- #define Min(num1,num2) if(num1>num2) num1=num2
- #define Max(num1,num2) if(num1<num2) num1=num2
- #define key 11380
- //using namespace std ;
- int f[][][][],L1,L2,L3,D;
- int main(){
- freopen("secret.in","r",stdin);
- freopen("secret.out","w",stdout);
- scanf("%d%d%d%d",&L3,&L2,&L1,&D);
- for(int i=;i<=D;i++) f[][][][i]=;
- for(int d=;d<=D;d++)
- for(int l1=;l1<=L1;l1++)
- for(int l2=;l2<=L2;l2++)
- for(int l3=;l3<=L3;l3++)
- if(l1||l2||l3){
- int sum=;
- //{ }
- for(int i=;i<=l1;i++)
- for(int j=;j<=l2;j++)
- for(int k=;k<l3;k++)
- sum=(sum+f[i][j][k][d-]*f[l1-i][l2-j][l3-k-][d])%key;
- //[ ]
- for(int i=;i<=l1;i++)
- for(int j=;j<l2;j++)
- sum=(sum+f[i][j][][d-]*f[l1-i][l2-j-][l3][d])%key;
- //( )
- for(int i=;i<l1;i++)
- sum=(sum+f[i][][][d-]*f[l1--i][l2][l3][d])%key;
- f[l1][l2][l3][d]=sum;
- }
- printf("%d",(f[L1][L2][L3][D]-f[L1][L2][L3][D-]+key)%key);
- }
Genotype&&陨石的秘密的更多相关文章
- poj[1187][Noi 01]陨石的秘密
Description 公元11380年,一颗巨大的陨石坠落在南极.于是,灾难降临了,地球上出现了一系列反常的现象.当人们焦急万分的时候,一支中国科学家组成的南极考察队赶到了出事地点.经过一番侦察,科 ...
- POJ 1187 陨石的秘密 (线性DP)
题意: 公元11380年,一颗巨大的陨石坠落在南极.于是,灾难降临了,地球上出现了一系列反常的现象.当人们焦急万分的时候,一支中国科学家组成的南极考察队赶到了出事地点.经过一番侦察,科学家们发现陨石上 ...
- [POJ1187] 陨石的秘密
问题描述 公元11380年,一颗巨大的陨石坠落在南极.于是,灾难降临了,地球上出现了一系列反常的现象.当人们焦急万分的时候,一支中国科学家组成的南极考察队赶到了出事地点.经过一番侦察,科学家们发现陨石 ...
- 【POJ1187】陨石的秘密
题目大意: 定义一个串:只含有 '( )','[ ]','{ }',3种(6个)字符. 定义 SS 串: 空串是SS表达式. 若A是SS表达式,且A串中不含有中括号和大括号,则(A)是SS表达式. 若 ...
- 题解 【POJ1187】 陨石的秘密
解析 考虑到数据范围,其实我们可以用记搜. 设\(f[a][b][c][d]\)表示还剩\(a\)个'{}',\(b\)个"[]",\(c\)个"()",深度\ ...
- AcWing 317. 陨石的秘密
1 -> {} 2 -> [] 3 -> () \(f[d][a][b][c]\) 表示 \([i * 2 - 1, j * 2]\) 这段区间 深度为 d \(1\) 有 \(a\ ...
- 别人整理的DP大全(转)
动态规划 动态规划 容易: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ...
- dp题目列表
此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...
- dp式子100个……
1. 资源问题1-----机器分配问题F[I,j]:=max(f[i-1,k]+w[i,j-k]) 2. 资源问题2------01背包问题F[I,j]:=max(f[i- ...
随机推荐
- ASP.NET的GET和POST方式的区别归纳总结
表单提交中,ASP.NET的Get和Post方式的区别归纳如下 几点: 1. get是从服务器上获取数据,post是向服务器传送数据. 2. get是把参数数据队列加到提交表单的ACTION属性所指 ...
- Android学习6—单元测试的使用
在这里对单元测试的使用,主要介绍两种方法,1.手动添加配置信息,然后编写测试类.2.通过Eclipse创建测试项目 1.手动添加配置信息,然后编写测试类: 待测试的类:/src/com/example ...
- django 学习点滴
django连接数据库要安装第三方包,比如mysql的就是 python-mysqldb, 用apt-cache search python-mysql 搜索一下. django的project可以放 ...
- 如何在Html的div+css中去除<li>标签前面小黑点,和ul、LI部分属性方法
div是很多人做网站都会用到的,但在显示效果时前面总是会有一个小黑点,这个效果很多人不想要,但又不知到如何去除,然而我们可以用以下方法来清除. 1.在CSS中写入代码.找到相关性的CSS,在..li和 ...
- 获取DOM的真实节点
<script type="text/babel"> var Myelement=React.createClass({ handleClick:function(){ ...
- IE6下解决select层级高的问题
div在IE6下无法遮盖select,原因是在IE6下,浏览器将select元素视为窗口级元素,这时div或者其它的普通元素无论z-index设置的多高都是无法遮住select元素的. 解决方法有三种 ...
- css 浮动 相对定位 绝对定位区别
今天下班在地铁上看了一个样式教学视频,因为最近在学习前端.以前刚毕业的时候,感觉后台才是王道,但最近发现,前端也很重要,比如:自己接一些私单做的时候,自己要根据需求做好界面,才能更加符合客户需求,不然 ...
- [Jquery] js获取浏览器滚动条距离顶端的距离
需要用js获取滚动条距离窗口顶端的距离和js获取浏览器可视化窗口的大小 一.jQuery获取的相关方法 jquery 获取滚动条高度 获取浏览器显示区域的高度 : $(window).height( ...
- CAS单点登录配置[2]:证书生成
上一篇介绍了准备工作,本片将介绍如何生成证书. 服务器端证书 1 我们在F盘下建立一个cas文件夹,在此文件夹中生成证书文件,打开命令窗口,进入此目录下,如图: 2 生成服务器端证书, 此命令用于在当 ...
- 使用reuseport和recvmmsg优化UDP服务器
http://skoo.me/system/2014/03/18/udp-server-performance/ http://www.helplib.net/s/linux.die/65_3223/ ...