您的位置:首页 > 其它

hdu 5677 ztr loves substring 多重背包

2016-05-02 20:06 453 查看
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 178 Accepted Submission(s): 93


[align=left]Problem Description[/align]
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".

[align=left]Input[/align]
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.

[align=left]Output[/align]
For each test,Output a line.If can output "True",else output "False".

[align=left]Sample Input[/align]

3
2 3 7

yjqqaq
claris
2 2 7
popoqqq
fwwf

1 3 3
aaa

[align=left]Sample Output[/align]

False
True

True

[align=left]Source[/align]
BestCoder Round #82 (div.2)

思路:二维费用的

#include <bits/stdc++.h>
using namespace std;
const int N = 105;
const int INF = 0x3f3f3f3f;
int Ma[N << 1], Mp[N << 1];
char s
;
int cnt
;

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

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


View Code

,且二维都要求恰好装满,那么初始化[0][0]能满足,其它状态都不满足
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: