zoukankan      html  css  js  c++  java
  • [HDU5677]ztr loves substring

    ztr loves substring

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

    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
     
    题解:
    (多重背包都快不会打了我已经完蛋了)
    这道题相对来说还是比较裸的。先用manacher计算出每种长度回文串出现的个数。
    在将长度视为物品跑一个多重背包即可。
    关于这里的背包,我们可以设f[i][j]为一个bool滚动数组,表示构造长度为i的串用了j个子串能不能成立。
    那么显然3层循环即可。我打的是二进制分解然后01背包(其实是因为单调队列不会)
    代码见下:
     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 const int N=110;
     5 int n,t,m,k,ct,mx,l;
     6 int r[N<<1],f[N][N],vis[N];
     7 char s[N<<1],str[N];
     8 inline int max(int a,int b){return a>b?a:b;}
     9 inline int min(int a,int b){return a<b?a:b;}
    10 inline void manacher()
    11 {
    12     memset(s,0,sizeof(s));
    13     n=0;m=strlen(str);
    14     s[n++]=1;s[n++]=2;
    15     for(int i=0;i<m;i++)s[n++]=str[i],s[n++]=2;
    16     memset(r,0,sizeof(r));ct=mx=0;
    17     for(int i=0;i<n;i++)
    18     {
    19         if(i<mx)r[i]=min(mx-i,r[2*ct-i]);
    20         else r[i]=1;
    21         while(0<=i-r[i]&&i+r[i]<n&&s[i-r[i]]==s[i+r[i]])r[i]++;
    22         if(i+r[i]>mx)ct=i,mx=i+r[i];
    23         int j=r[i]-1;
    24         while(j>=0)vis[j]++,j-=2;
    25     }
    26 }
    27 int c[N*N],v[N*N],cnt;
    28 inline bool backpack()
    29 {
    30     memset(f,0,sizeof(f));
    31     for(int i=1;i<=l;i++)
    32     {
    33         int tmp=1;
    34         while(vis[i]>=tmp)
    35             c[++cnt]=tmp*i,v[cnt]=tmp,vis[i]-=tmp,tmp<<=1;
    36         if(vis[i])
    37             c[++cnt]=vis[i]*i,v[cnt]=vis[i];
    38     }
    39     f[0][0]=1;
    40     for(int u=1;u<=cnt;u++)
    41         for(int i=l;i>=c[u];i--)
    42             for(int j=k;j>=v[u];j--)
    43                 f[i][j]|=f[i-c[u]][j-v[u]];
    44     return f[l][k];
    45 }
    46 int main()
    47 {
    48     int cnt;scanf("%d",&cnt);
    49     while(cnt--)
    50     {
    51         scanf("%d%d%d",&t,&k,&l);
    52         memset(vis,0,sizeof(vis));
    53         for(int i=1;i<=t;i++)
    54             scanf("%s",str),manacher();
    55         if(backpack())printf("True
    ");
    56         else printf("False
    ");
    57     }
    58 }
    HDU5677
  • 相关阅读:
    2016/11/2
    2016/11/1
    bzoj 3809: Gty的二逼妹子序列
    bzoj 1207: [HNOI2004]打鼹鼠
    bzoj 1191: [HNOI2006]超级英雄Hero
    BZOJ 1854: [Scoi2010]游戏
    BZOJ 1296: [SCOI2009]粉刷匠
    BZOJ 1787: [Ahoi2008]Meet 紧急集合
    tarjan算法
    高级的暴力(一)——分块
  • 原文地址:https://www.cnblogs.com/LadyLex/p/7143207.html
Copyright © 2011-2022 走看看