hdoj 5677 ztr loves substring

来源:互联网 发布:mac魅可官网 编辑:程序博客网 时间:2024/05/16 11:56

  这是一场BC里的题,虽然这套题非常辣鸡,但这题对我来说还是有学习价值的。
  首先是暴力跑一下,统计一下不同长度的回文串分别有多少个,然后就是跑存在性的多重背包了,二进制思想不错!

#include <iostream>    #include <stdio.h>    #include <cmath>    #include <algorithm>    #include <string>  #include <string.h>    #include <memory.h>    #include <vector>    #include <queue>    #include <stack> using namespace std;#define ll long long char str[111];int cnt[111];bool dp[111][111];int main(){    int T;    cin>>T;    while(T--){        memset(cnt,0,sizeof(cnt));        int N,K,L;        cin>>N>>K>>L;        for(int i=1;i<=N;i++){            scanf("%s",str);            int len = strlen(str);            //odd            for(int i=0;i<len;i++){                int l = 0;                for(int l=0;;l++){                    if(i-l<0 || i+l==len){                        break;                    }                    if(str[i-l]==str[i+l]){                        cnt[l*2+1]++;                    }else{                        break;                    }                }            }            //even            for(int i=0;i<len-1;i++){                int l = 0;                for(int l=0;;l++){                    if(i-l<0 || i+l+1==len){                        break;                    }                    if(str[i-l]==str[i+l+1]){                        cnt[l*2+2]++;                    }else{                        break;                    }                }            }        }        //dp数组: 用了几个串 当前长度  的可达性         memset(dp,0,sizeof(dp));        dp[0][0] = 1;        for(int i=1;i<=100;i++){            if(dp[K][L]){                break;             }            //二进制拆解             int num = cnt[i];            int kk = 1;            if(!num)continue;            while(kk < num){                for(int j=K;j>=kk;j--){                    for(int k=L;k>=i*kk;k--){                        if(dp[j-kk][k-i*kk]){                            dp[j][k] = 1;                        }                    }                }                num -= kk;                kk<<=1;            }            if(!num)continue;            for(int j=K;j>=num;j--){                for(int k=L;k>=i*num;k--){                    if(dp[j-num][k-i*num]){                        dp[j][k] = 1;                    }                }            }        }        if(dp[K][L]){            printf("True\n");        }else{            printf("False\n");        }    }    return 0;}
0 0