Attached topic Link: http://acm.hdu.edu.cn/showproblem.php?pid=5677
Problem description
ZTR like to study the substring, today, he has n string now ztr want to know, can from all the palindrome string of n string, take out exactly k palindrome string and satisfy these palindrome string length of the sum for L to Yjqqaq for example this string contains the palindrome string has Y,J,Q,A,Q,QQ, Qaq so we can choose both QQ, and choose Qaq
Enter a description
There is a T group of data, the first behavior is a positive integerT (t<=10)T(T<=10) The first behavior of each group of data three positive integersN (1<=n<=100), K (1<=k<=100), L (l<=100)N(1<=N <=100) Span class= "mpunct" >,k (1 <=k<= 100) ,l (l< =100) next n rows, one string of lowercase letters per line, Ensure that the length of each string does not exceed L
Output description
There is a T-line, if it can be composed then return true, and vice versa is False
Attach the official task, it should be easy to understand,
First, for each string I run once manancher, make g[i][j]=p[j]-1g[i][j]=p[J ]−1
In this way, G stores the length of all palindrome strings.
For convenience, reduce g to one-dimensional representation
You might want to abstract each substring into an object.
The cost is two-dimensional, i.e. {length, 1}
Value is of type bool
So it becomes a two-dimensional evaluation of the feasibility of cost knapsack problem
Set f (i,j)f(I,J) indicates that the currently selected length is I, has selected J-string, this state can be reached
F (i,j) =f (i,j) |f (I-g (k), j-1)< Span class= "Mord mathit" >f (i,j" =f (i,j) ∣f (i− g (k,j−1 )
In this way, the time complexity is O (l*k*n^{2})o(L∗K∗N? 2?? )
Well, obviously not.
We analyzed and found that G is a lot of repetition.
Then treat it as a multi-pack.
Time complexity reduced to O (l*k*n*log\sum Li)o(L∗K∗N∗lOg∑L i)
Note: Using Manacher to handle the length of the longest palindrome in a certain location, we should also split this into n palindrome string, assuming that the length of the palindrome string is odd so can be split into a length of 1 3 5 ... The even number can be split into 2 4 6 ...
The code is as follows:
#include <cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespacestd;intN, K, L;intlen_num[ the];Charstr[ Max];Chara[ -];intp[ -];//ManachervoidManacher (Char*s) {intLen = strlen (s+1); intm =2*len +1; for(intI=1; i<=len; i++) {A[i<<1] =Str[i]; A[i<<1|1] ='#'; } a[0] ='+'; a[1] ='#'; a[m+1] ='-';//cout<<a<<endl; intmx=0, IDX; for(intI=1; i<=m; i++){ if(MX >i) p[i]= Min (mx-i, p[2*idx-i]); ElseP[i]=1; for(; a[i+p[i]]==a[i-p[i]]; p[i]++); if(P[I]+I>MX) Mx=p[i]+i, idx=i; if(p[i]-1) { if((p[i]-1) &1) for(intA=1; a<=p[i]-1; a+=2) len_num[a]++; Else for(intA=2; a<=p[i]-1; a+=2) len_num[a]++; } }//for (int i=1; i<=m; i++)//cout<<p[i]<< ";//cout<<endl;}intdp[ the][ the];//Select I string can make a string of length JintMain () {intT; scanf ("%d", &T); while(t--) {scanf ("%d%d%d", &n, &k, &m); memset (Len_num,0,sizeof(Len_num)); for(intI=0; i<n; i++) {scanf ("%s", str+1); Manacher (str); } memset (DP,0,sizeof(DP)); dp[0][0] =1; for(intI=1; i<= -; i++){ intnum =Len_num[i]; for(intk=1; Num>0; k<<=1){//the length of I was selected for Mul intMul =min (k, num); for(intA= -; a-mul>=0; a--) for(intb= -; b-mul*i>=0; b--){//Dp[a][b] | | = Dp[a-mul][b-mul*i];DP[A][B] = Dp[a][b] | | dp[a-mul][b-mul*i]; } num-=Mul; } } if(Dp[k][l]) printf ("true\n"); Elseprintf ("false\n"); } return 0;}
HDU5677 Manacher + two-dimensional multiple backpack