• hdu 5677 ztr loves substring 二维费用背包+回文


    题目链接: hdu 5677 ztr loves substring

    官方题解:

    //这部分是错的(首先,对于每一个串i跑一次manancher,令g[i][j]=p[j]-1g[i][j]=p[j]1

    这样,g就存储了所有的回文子串的长度

    为了方便,把g降到一维表示)

    首先,因为字符串长度较小,所以直接二重for循环找就好了,用一个数组 g记录各个回文串的长度

    不妨把每一个子串抽象成一个物品

    费用为二维的,即{长度,1}

    价值是Bool型的

    这样就成了一个二维判断可行性费用背包问题

    f(i,j)f(i,j)表示当前选出的长度为i,已经选了j个串,这个状态能否达到

    f(i,j)=f(i,j)|f(i-g(k),j-1)f(i,j)=f(i,j)f(ig(k),j1)

    这样,时间复杂度为O(L*K*N^{2})O(LKN2​​)

    显然还是过不去

    我们分析,发现其实g是会大量重复的

    那么不妨当做多重背包来处理

    时间复杂度降为O(L*K*N*logsum Li)O(LKNlogLi)

    /**************************************************************
        Problem:hdu 5677
        User: youmi
        Language: C++
        Result: Accepted
        Time:31MS
        Memory:2264K
    ****************************************************************/
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#include<bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <set>
    #include <sstream>
    #include <cmath>
    #include <queue>
    #include <deque>
    #include <string>
    #include <vector>
    #define zeros(a) memset(a,0,sizeof(a))
    #define ones(a) memset(a,-1,sizeof(a))
    #define sc(a) scanf("%d",&a)
    #define sc2(a,b) scanf("%d%d",&a,&b)
    #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define scs(a) scanf("%s",a)
    #define sclld(a) scanf("%I64d",&a)
    #define pt(a) printf("%d
    ",a)
    #define ptlld(a) printf("%I64d
    ",a)
    #define rep0(i,n) for(int i=0;i<n;i++)
    #define rep1(i,n) for(int i=1;i<=n;i++)
    #define rep_1(i,n) for(int i=n;i>=1;i--)
    #define rep_0(i,n) for(int i=n-1;i>=0;i--)
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define lson (step<<1)
    #define rson (lson+1)
    #define esp 1e-6
    #define oo 0x3fffffff
    #define TEST cout<<"*************************"<<endl
    
    using namespace std;
    typedef long long ll;
    
    int n,K,L;
    
    const int maxn=200+10;
    char s[maxn];
    char p[maxn<<1];
    int dp2[maxn<<1];
    int str[maxn<<1];
    int dp[maxn<<1][maxn<<1];
    void manacher(int len)
    {
        int l=0;
        p[l++]='$';
        p[l++]='#';
        for(int i=0;i<len;i++)
        {
            p[l++]=s[i];
            p[l++]='#';
        }
        p[l]=0;
        int mx=0,id=0;
        for(int i=0;i<l;i++)
        {
            dp2[i]=mx>i?Min(dp2[2*id-i],mx-i):1;
            while(p[dp2[i]+i]==p[i-dp2[i]])
                dp2[i]++;
            if(mx<dp2[i]+i)
            {
                id=i;
                mx=dp2[i]+i;
            }
        }
    }
    int check(int l,int r)
    {
        for(int i=l,j=r;i<=j;i++,j--)
            if(s[i]!=s[j])
                return 0;
        return 1;
    }
    void zeroone(int len,int num)
    {
        for(int i=L;i>=len;i--)
            for(int j=K;j>=num;j--)
                if(dp[i-len][j-num])
                    dp[i][j]++;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
        int T_T;
        scanf("%d",&T_T);
        for(int kase=1;kase<=T_T;kase++)
        {
            sc3(n,K,L);
            zeros(str);
            rep0(i,n)
            {
                scs(s);
                int len=strlen(s);
                /**manacher(len);
                for(int i=2;i<=2*len;i+=2)
                    str[dp2[i]-1]++,mx=Max(mx,dp2[i]-1);*/
                for(int i=0;i<len;i++)
                    for(int j=i;j<len;j++)
                        if(check(i,j))
                            str[j-i+1]++;
            }
            zeros(dp);//下面就是二维背包了
            dp[0][0]=1;
            for(int i=1;i<=L;i++)
            {
                if(str[i]==0)
                    continue;
                int cnt=1;
                while(cnt<str[i])
                {
                    zeroone(i*cnt,cnt);
                    str[i]-=cnt;
                    cnt<<=1;
                }
                zeroone(i*str[i],str[i]);
            }
            puts(dp[L][K]?"True":"False");
        }
    }
    不为失败找借口,只为成功找方法
  • 相关阅读:
    简单爬取腾讯新闻内容方法封装
    Python正则表达式函数
    Escape(反思与总结)
    springboot中使用mybatis
    解决 java.lang.UnsatisfiedLinkError:no ** in java.library.path in java.library.path 的异常
    解决 fatal error: jni_md.h: No such file or directory #include “jni_md.h”
    Git troubleshooting
    Java8 新特性2——强大的Stream API
    Java8 新特性1—— Lambda表达式、内置函数式接口、方法引用与构造器引用
    搭建Linux(Ubuntu)系统下的Differential Datalog运行环境
  • 原文地址:https://www.cnblogs.com/youmi/p/5453492.html
Copyright © 2020-2023  润新知