您的位置:首页 > 其它

HDU 5677 ztr loves substring

2016-05-02 19:57 260 查看
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

3
2 3 7
yjqqaq
claris
2 2 7
popoqqq
fwwf
1 3 3
aaa

 

Sample Output

False
True
True

刚好上个月学了回文树,这题可以把全部的串插进回文树里,然后统计每个有多少,然后就是多重背包问题了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long LL;
const int maxn = 1e2 + 10;
int T, n, w, m, c[maxn], f[maxn][maxn];
char s[maxn];

struct PalindromicTree
{
const static int maxn = 1e5 + 10;
const static int size = 26;
int next[maxn][size], last, sz, tot;
int fail[maxn], len[maxn], cnt[maxn];
char s[maxn];
int Node(int length)
{
memset(next[sz], 0, sizeof(next[sz]));
len[sz] = length; cnt[sz] = 0; return sz++;
}
void clear()
{
sz = last = fail[2] = fail[1] = 1;
Node(-1); Node(tot = 0);
}
void reset()
{
last = 1; tot = 0;
}
int getfail(int x)
{
while (s[tot] != s[tot - len[x] - 1]) x = fail[x];
return x;
}
void add(char pos)
{
int x = (s[++tot] = pos) - 'a', y = getfail(last);
if (!(last = next[y][x]))
{
last = next[y][x] = Node(len[y] + 2);
fail[last] = len[last] == 1 ? 2 : next[getfail(fail[y])][x];
}
++cnt[last];
}
void work()
{
memset(f, 0, sizeof(f));
memset(c, 0, sizeof(c));
for (int i = sz - 1; i > 2; i--)
{
cnt[fail[i]] += cnt[i];
c[len[i]] += cnt[i];
}
f[0][0] = 1;
for (int i = 1; i <= 100; i++)
{
for (int j = 1; c[i] > 0; j <<= 1)
{
int a = i*(j <= c[i] ? j : c[i]), b = j <= c[i] ? j : c[i];
c[i] -= j;
for (int k = w; k >= b; k--)
{
for (int kk = m; kk >= a; kk--)
{
f[k][kk] = f[k][kk] || f[k - b][kk - a];
}
}
}
}
printf("%s\n", f[w][m] ? "True" : "False");
}
}solve;

int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d%d%d", &n, &w, &m);
solve.clear();
while (n--)
{
scanf("%s", s); solve.reset();
for (int i = 0; s[i]; i++) solve.add(s[i]);
}
solve.work();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU