hdoj ztr loves substring 5677 (多重背包+母函数)好题

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
   
   
   
   
False True True
 

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;
} 

你可能感兴趣的:(hdoj ztr loves substring 5677 (多重背包+母函数)好题)