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)

代码如下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<string>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<cmath>
 7 #define LL long long
 8 #define INF 99999999
 9 #define Min(num1,num2) if(num1>num2) num1=num2
10 #define Max(num1,num2) if(num1<num2) num1=num2
11 using namespace std;
12 int n,f[101][101],g[101],num[101],map[101][101];
13 string s;
14 void work(){
15     memset(f,0,sizeof f);
16     cin>>s;
17     int l=s.size();
18     for(int k=1,i=0;i<l;k++,i++) f[k][k]=num[s[i]-'A'];
19     for(int p=1;p<=l;p++)
20         for(int i=1;i<=l;i++){
21             int j=i+p;
22             if(j>l) break;
23             for(int k=i;k<j;k++)
24           for(int ci=0;ci<26;ci++)
25                     for(int cj=0;cj<26;cj++)                
26                         if((f[i][k]&num[ci])&&(f[k+1][j]&num[cj]))
27                             f[i][j]|=map[ci][cj];
28                         
29          }
30     int key='S'-'A';
31     for(int i=1;i<=l;i++) g[i]=INF;
32     g[0]=0;
33     for(int i=1;i<=l;i++)
34         for(int j=1;j<=i;j++)
35             if((f[j][i]&num[key])&&g[j-1]!=INF)
36                 Min(g[i],g[j-1]+1);
37     g[l]==INF ? printf("NIE\n") : printf("%d\n",g[l]);
38 } 
39 int main(){
40         freopen("GEN.in","r",stdin);
41         freopen("GEN.out","w",stdout);
42       scanf("%d\n",&n);
43         num[0]=1;
44          for(int i=1;i<=26;i++) num[i]=num[i-1]<<1;
45       for(int a,b,c,i=1;i<=n;i++){
46             a=getchar()-'A';
47              b=getchar()-'A';
48              c=getchar()-'A';
49              map[b][c]|=num[a];
50          getchar();
51          }
52          int T;
53          scanf("%d\n",&T);
54       while(T--) work();  
55 }
View Code

相关文章: