Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 178 Accepted Submission(s): 93
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".
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.
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
思路:二维费用的
#include <bits/stdc++.h> using namespace std; const int N = 105; const int INF = 0x3f3f3f3f; int Ma[N << 1], Mp[N << 1]; char s[N]; int cnt[N]; void manacher(char s[], int len) { int l = 0; Ma[l++] = '$'; Ma[l++] = '#'; for(int i = 0; i < len; ++i) { Ma[l++] = s[i]; Ma[l++] = '#'; } Ma[l] = 0; int mx = 0, id = 0; for(int i = 0; i < l; ++i) { Mp[i] = mx > i ? min(Mp[2 * id - i], mx - i) : 1; while(Ma[ i + Mp[i] ] == Ma[ i - Mp[i] ]) Mp[i]++; if(i + Mp[i] > mx) mx = i + Mp[i], id = i; } for(int i = 0; i < l; ++i) if(Mp[i] > 1) { int p; if(Mp[i] & 1) p = 2; else p = 1; for(int j = p; j < Mp[i]; j += 2) cnt[j]++; } } int dp[N][N]; void Dp1(int v, int k, int l) { for(int i = v; i <= l; ++i) for(int j = 1; j <= k; ++j) if(dp[i - v][j - 1]) dp[i][j] = 1; } void Dp2(int v, int num, int k, int l) { for(int i = l; i >= v; --i) for(int j = k; j >= num; --j) if(dp[i - v][j - num]) dp[i][j] = 1; } void to(int x, int k, int l) { if(cnt[x] >= k && x * cnt[x] >= l) Dp1(x, k, l); else { int s = 1, tot = cnt[x]; while(s < tot) { Dp2(x * s, s, k, l); tot -= s; s <<= 1; } Dp2(tot * x, tot, k, l); } } bool solve(int k, int l) { memset(dp, 0, sizeof dp); dp[0][0] = 1; for(int i = 1; i <= 100; ++i) if(cnt[i]) to(i, k, l); if(dp[l][k]) return true; return false; } int main() { // freopen("in", "r", stdin); int _; scanf("%d", &_); while(_ --) { int n, k, l; scanf("%d%d%d", &n, &k, &l); memset(cnt, 0, sizeof cnt); for(int i = 0; i < n; ++i) { scanf("%s", s); int len = strlen(s); manacher(s, len); } if(solve(k, l)) puts("True"); else puts("False"); } return 0; }
,且二维都要求恰好装满,那么初始化[0][0]能满足,其它状态都不满足