HDU 5677 ztr loves substring （dp) - dblank

# HDU 5677 ztr loves substring （dp)

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<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int inf =0x3f3f3f3f;
const double  pi = acos(-1.0);
const int N = 1e2 + 10;
char str[N][N][N];
int dp[N][N], bag[N*N*N], yes[N][N], cnt[N], cnt1[N*N*N];
void manachar(char *ss)
{
int l = strlen(ss);
int len[N*2];
memset(len, 0, sizeof(len));
for(int i = l; i>=0; i--)
{
ss[i*2+2] = ss[i];
ss[i*2+1] = '#';
}
ss[0] = '*';
int id = 0;
for(int i = 1; i<l*2+2; i++)
{
if(len[id] + id > i)
len[i] = min(len[id*2 - i], len[id] + id - i);
else len[i] = 1;
while(ss[i + len[i]] == ss[i - len[i]]) len[i]++;
if(id + len[id] < i + len[i]) id = i;
if(ss[i] == '#' && len[i] == 1)continue;
cnt[len[i]-1]++;
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n, k, l;
char s[2*N];
scanf("%d%d%d", &n, &k, &l);
memset(cnt, 0, sizeof(cnt));
memset(dp, 0, sizeof(dp));
for(int i = 0; i<n; i++)
{
scanf("%s", s);
manachar(s);
}
int kk = 0;
for(int i = 1; i<=100; i++)
{
int tmp = 1;
while(cnt[i]>=tmp)
{
bag[kk] = tmp*i, cnt1[kk++] = tmp;
cnt[i] -= tmp;
tmp*=2;
}
if(cnt[i])
bag[kk] = tmp*i, cnt1[kk++] = tmp;
}
dp[0][0] = 1;
for(int i = 0; i<kk; i++)
{
for(int j = l; j>=bag[i]; j--)
{
for(int r = cnt1[i]; r<=k; r++)
{
dp[r][j] |= dp[r-cnt1[i]][j - bag[i]];
}
}
}
if(dp[k][l])
printf("True\n");
else printf("False\n");
}
return 0;
}