HDU 5667

来源:互联网 发布:浙大网新 人工智能龙头 编辑:程序博客网 时间:2024/06/02 03:53

Problem Description
ztr love reserach substring.Today ,he has n string.Now ztr want to konw,can he take out exactly k palindrome from all substring of these n string,and thrn sum of length of these k substring is L.

for example string "yjqqaq"
this string contains plalindromes:"y","j","q","a","q","qq","qaq".
so we can choose "qq" and "qaq".
 

Input
The first line of input contains an positive integer T(T<=10) indicating the number of test cases.

For each test case:

First line contains these positive integer N(1<=N<=100),K(1<=K<=100),L(L<=100).
The next N line,each line contains a string only contains lowercase.Guarantee even length of string won't more than L.
 

Output
For each test,Output a line.If can output "True",else output "False".
 

Sample Input
32 3 7yjqqaqclaris2 2 7popoqqqfwwf1 3 3aaa
 

Sample Output
FalseTrueTrue


样例很有趣对不对

这题是用Manacher或回文自动机求出所有的回文串的长和数量

然后就转化成了bool DP多重背包

#include <stdio.h>#include <cstring>#include <algorithm>#include <iostream>using namespace std;int T,n,k,l;char s[105];int len[105],ch[105][26],num[105],fail[105],tot,num_len[105];int val[105*105],c[105*105],cnt;bool f[105][105];void clear(){    tot=0;    memset(ch,0,sizeof ch);    memset(num,0,sizeof num);    memset(fail,0,sizeof fail);    memset(len,0,sizeof len);}inline int get_fail(int x,int le){    while(s[le-len[x]-1]!=s[le])x=fail[x];    return x;}inline int newnode(int x){    len[tot]=x;    return tot++;}void build(char *s){    newnode(0);newnode(-1);    fail[0]=1;s[0]=-1;    int last=0,Ans=0;    for(int i=1;s[i];i++){        s[i]-='a';        int rt=get_fail(last,i);        if(ch[rt][s[i]]==0){            int now = newnode(len[rt]+2);            Ans = max(Ans,len[now]);            fail[now]=ch[get_fail(fail[rt],i)][s[i]];            ch[rt][s[i]]=now;        }        num[last=ch[rt][s[i]]]++;    }}bool Dp(){    memset(f,0,sizeof f);    cnt=0;    for(int i=1;i<=100;i++){        int tmp=1;        while(num_len[i]>=tmp){            val[++cnt]=i*tmp;            c[cnt]=tmp;            num_len[i]-=tmp;            tmp*=2;        }        if(num_len[i]){            val[++cnt]=num_len[i]*i;            c[cnt]=num_len[i];        }    }      f[0][0]=1;    for(int i=1;i<=cnt;i++)        for(int j=l;j>=val[i];j--)            for(int o=c[i];o<=k;o++)                f[j][o]|=f[j-val[i]][o-c[i]];    return f[l][k];}int main(){    scanf("%d",&T);    while(T--){        scanf("%d%d%d",&n,&k,&l);        memset(num_len,0,sizeof num_len);        for(int i=1;i<=n;i++){            scanf("%s",s+1);            clear();build(s);            for(int j=tot;j>=0;j--){                num[fail[j]]+=num[j];                num_len[len[j]]+=num[j];            }        }        if(Dp())printf("True\n");        else printf("False\n");    }}




原创粉丝点击