您的位置:首页 > 其它

hdu 5677-ztr loves substring

2016-05-14 10:49 351 查看


ztr loves substring

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 299 Accepted Submission(s): 164



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)

解题报告:

典型的背包问题,适当变种,并需要做一些优化,否则会超时。dp[i][j]是一个set,用于表示扫描到第i个包时,当前总量正好达到j时,每种装包方案的装包个数。因此dp[i][j]的集合就是dp[i-1][j-a[j]]的集合元素每个值+1。注意做好初始化,另外当前包的状态只与前一个状态有关,因此可以状态压缩,每次内循环从后向前扫描即可。重量为x的包最多只需要L/x+1个包就能装好,所以可以优化,否则请试试一百个字符且L为100时耗时多少。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
#include <vector>
using namespace std;

#define max(x, y) ((x) > (y) ? (x) : (y))
#define min(x, y) ((x) < (y) ? (x) : (y))

#define maxn 500010
int a[maxn];
#define maxl 105
set<int> dp[maxl];
int b[maxl]; /// 优化,记录每个长度的个数
typedef set<int>::iterator siter;

int N, K, L;
int ct;

void CountPar(const char sz[])
{
int len = strlen(sz);
for (int i = 0; i < len; ++i)
{
// mid
for (int j = 0; i - j >= 0 && i + j < len && 2 * j + 1 <= L; ++j)
{
if (sz[i-j] == sz[i+j])
{
//a[ct++] = 2 * j + 1;
++b[2*j+1];
}
else
break;
}

// right
for (int j = 0; i - j >= 0 && i + j + 1< len && 2 * (j + 1) <= L; ++j)
{
if (sz[i-j] == sz[i+j+1])
{
//a[ct++] = 2 * (j + 1);
++b[2*(j+1)];
}
else
break;
}
}
}

void Solve()
{
dp[0].insert(0);
dp[a[0]].insert(1);
for (int i = 1; i < ct; ++i)
{
for (int j = L; j >= 0; --j)
{
int preSum = j - a[i];
if (preSum < 0) continue;

for (siter it = dp[preSum].begin(); it != dp[preSum].end(); ++it)
{
int tmp = (*it) + 1;
dp[j].insert((*it) + 1);
if (j == L && tmp == K)
{
printf("True\n");
return;
}
}
}
}

for (siter it = dp[L].begin(); it != dp[L].end(); ++it)
{
if (*it == K)
{
printf("True\n");
return;
}
}

printf("False\n");
}

int main()
{
//freopen("input.txt", "r", stdin);

int cas;
scanf("%d", &cas);
for (int i = 1; i <= cas; ++i)
{
scanf("%d %d %d", &N, &K, &L);

ct = 0;
for (int i = 0; i < L; ++i)
{
dp[i].clear();
}
memset(b, 0, sizeof(b));

char sz[maxl] = {0};
for (int i = 0; i < N; ++i)
{
scanf("%s", sz);
CountPar(sz);
}
// 优化
for (int i = 1; i <= L; ++i)
{
for (int j = 1; j <= b[i] && j * i <= L; ++j)
{
a[ct++] = i;
}
}

Solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: