HOJ 13830 DNA Sequencing

Problem description
Finally, Plankton’s attempts to steal the Krabby Patty formula succeeded and it eventually put the Krusty Krab out of business. So, SpongeBob and his co-workers decided to switch to a brand new job. Their new startup is Krusty-Royan, a biological research institute whose main focus is on DNA sequencing. Their first customer is Sandy, the squirrel scientist, who has found the corpse of an alien from the outer space and asked Krusty-Royan crew to extract its DNA sequence. Contrary to the life on earth, the DNA of the alien was not only composed of the 4 well-known nucleotides (A, C, G, and T), but all 26 English letters! So, each part of its DNA is a sequence of capital English letters. Given the alien tissue, the DNA sequencer machine extracted a number of (not necessarily distinct) DNA sequences and printed them on paper, one per line. Based on the contract, a DNA sequence is valid only if its length is at least M, and Sandy will pay one dollar for each distinct valid DNA sequence. So, Mr. Krabs, the greedy boss of Krusty-Royan has asked SpongeBob to use a correction pen and erase some letters from the end of the sequences printed on the paper in order to maximize the number of distinct valid DNA sequences. Your job is to help SpongeBob find the maximum number of distinct valid DNA sequences he can make.

Input
There are multiple test cases in the input. Each test case starts with a line containing two space-separated integers k and M (1 ⩽ k ⩽ 500; 1 ⩽ M ⩽ 500). Each of the next k lines starts with a number ni followed by a string si which means there are ni copies of DNA sequence si printed on the paper (1 ⩽ ni ⩽ 500). The length of the strings is a positive integer not greater than 500. The input terminates with a line containing 0 0 which should not be processed as a test case.

Output
For each test case, output a line containing the maximum number of distinct valid DNA sequences which SpongeBob can provide.

Sample Input
2 1
2 ABB
2 ABC
2 2
2 ABB
2 ABC
2 3
2 ABB
2 ABC
2 4
2 ABB
2 ABC
0 0
Sample Output
4
3
2
0

思路:字典树,可能会哈希的大佬可以哈希过,不熟的孩子,冲突啊冲突

这里建树的时候节点有两个元素,一个height目的是为了判断从根节点到这个子串是否合法,一个num表示这个子串我是否需要,同时满足就是我要的子串,累加上去就好;

这里给出队友和老师代码:

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=250020;
struct node
{
    int num,height,ch[26];
    void init(){num=height=0;memset(ch,0,sizeof ch);}
};
node tre[maxn];
int cnt=1;//节点下标
const int root=1;//根节点
void insert(int cur,const string &s,int i,int m,int Size)
{
    int id=s[i]-'A';
    if(tre[cur].ch[id]==0)tre[cur].ch[id]=++cnt;
    int ch=tre[cur].ch[id];//子节点
    tre[ch].height=i;
    if(Size==i+1)tre[ch].num+=m;//字符串全部插入,更新num
    else    insert(ch,s,i+1,m,Size);
}

int dfs(int cur,int h)
{
    int res=0;
    for(int i=0;i<26;i++)
    {
        if(tre[cur].ch[i]!=0)
        {
            int ch=tre[cur].ch[i];
            res+=dfs(ch,h);
            tre[cur].num+=max(tre[ch].num-1,0);
        }
    }
    if(tre[cur].height+1>=h&&tre[cur].num>0)res++;//既符合要求,又是我需要的子串;
    return res;
}
char s[510];
int main()
{
    freopen("input.txt","r",stdin);
    int n,k,m;
    while(scanf("%d%d",&n,&k),n)
    {
        cnt=1;
        for(int i=0;i<maxn;i++)
            tre[i].init();
        for(int i=0;i<n;i++)
        {
            scanf("%d%s",&m,s);
            int Size=strlen(s);
            insert(root,s,0,m,Size);
        }
        tre[root].height=-1;
        printf("%d\n",dfs(root,k));
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/MeowMeowMeow/p/7298678.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值