ztr loves substring
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 288 Accepted Submission(s): 159
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
Source
BestCoder Round #82 (div.2)
问题描述
ztr喜欢研究子串,今天,他有n个串
现在ztr想知道,能否从这n个串的所有回文子串中,
取出恰好k个回文串且满足这些回文串的长度之和为L
以yjqqaq为例
这个串包含的回文子串有
y,j,q,a,q,qq,qaq
所以我们可以既选qq,又选qaq
输入描述
有T组数据,第一行为一个正整数T(T<=10)T(T<=10)
每组数据第一行为三个正整数N(1<=N<=100),K(1<=K<=100),L(L<=100)N(1<=N<=100),K(1<=K<=100),L(L<=100)
接下来N行,每行一个由小写字母构成的字符串,保证每个串的长度不超过L
输出描述
有T行,如果能组成则返回True,反之为False
输入样例
3
2 3 7
yjqqaq
claris
2 2 7
popoqqq
fwwf
1 3 3
aaa
输出样例
False
True
True
//思路:
先将不同长度的回文串的个数存起来(cnt[i]表示长度为i的回文串的个数),然后运用母函数&多重背包求得是否可以找到满足条件的字符串。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define N 110
using namespace std;
int cnt[N];
int dp[N][N];
char ch[N];
void ct()
{
for(int i=0;ch[i]!='\0';i++)
{
for(int j=0;j<=i&&i+j<strlen(ch);j++)
{
if(ch[i-j]==ch[i+j])
cnt[j*2+1]++;
else
break;
}
for(int j=i,k=i+1;j>=0&&k<strlen(ch);j--,k++)
{
if(ch[j]==ch[k])
cnt[i-j+1+k-i]++;
else
break;
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(cnt,0,sizeof(cnt));
memset(dp,0,sizeof(dp));
int n,k,l;
scanf("%d%d%d",&n,&k,&l);
for(int i=0;i<n;i++)
{
scanf("%s",ch);
ct();
}
dp[0][0]=1;
for(int i=1;i<=l;i++)
{
if(!cnt[i])
continue;
for(int j=l-i;j>=0;j--)
{
for(int s=0;s<k;s++)
{
if(dp[j][s]==0)
continue;
for(int f=1;f<=cnt[i]&&f+s<=k;f++)
{
if(f*i+j>l)
break;
dp[f*i+j][f+s]=1;
}
}
}
}
if(dp[l][k]==1)
printf("True\n");
else
printf("False\n");
}
return 0;
}