• HDU 5677 ztr loves substring


    Manacher+二维费用多重背包 二进制优化

    这题是一眼标算....先计算出每个长度的回文串有几种,然后用二维费用的多重背包判断是否有解。

    多重背包做的时候需要二进制优化。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 300;
    int N, p[maxn];
    char str[maxn], b[maxn];
    int cnt[maxn];
    int n, k, L;
    bool dp[maxn][maxn];
    
    void init()
    {
        int i;
        for (i = 0; str[i]; i++) b[2 * i + 1] = '#', b[2 * i + 2] = str[i];
        N = 2 * i + 1;
        b[0] = '$', b[N] = b[N + 1] = '#';
    }
    
    void solve()
    {
        int i, id, max = 0;
        for (i = 1; i <= N; i++)
        {
            p[i] = i < max ? std::min(max - i, p[2 * id - i]) : 1;
            while (b[i + p[i]] == b[i - p[i]]) ++p[i];
            if (i + p[i] > max) max = i + p[i], id = i;
            cnt[p[i] - 1]++;
        }
    }
    int main()
    {
        int T; scanf("%d", &T);
        while (T--)
        {
            memset(dp, 0, sizeof dp); dp[0][0] = 1;
            memset(cnt, 0, sizeof cnt);
            scanf("%d%d%d", &n, &k, &L);
            while (n--){ scanf("%s", str); init(); solve(); }
            for (int i = 100; i >= 1; i--) 
                cnt[i] = cnt[i] + cnt[i + 2];
            for (int i = 100; i >= 1; i--)
            {
                if (cnt[i] == 0) continue;
                int val = i, num = cnt[i];
                int t = 1;
                while (num)
                {
                    if (num > t)
                    {
                        int tmp_val = val*t;
                        for (int d = L; d >= 0; d--)
                        {
                            for (int f = k; f >= 0; f--)
                            {
                                if (dp[d][f] == 0) continue;
                                if (d + tmp_val <= L&&f + t <= k)
                                    dp[d + tmp_val][f + t] = 1;
                            }
                        }
                        num = num - t;
                        t = t * 2;
                    }
                    else
                    {
                        int tmp_val = val*num; 
                        for (int d = L; d >= 0; d--)
                        {
                            for (int f = k; f >= 0; f--)
                            {
                                if (dp[d][f] == 0) continue;
                                if (d + tmp_val <= L&&f + num <= k)
                                    dp[d + tmp_val][f + num] = 1;
                            }
                        }
                        num = 0;
                    }
                }
            }
            if (dp[L][k]) printf("True
    ");
            else printf("False
    ");
        }
        return 0;
    }
  • 相关阅读:
    Android studio 安装已经下载好的gradle.zip文件【ubuntu 14.04 LTS环境】
    Python 2.7.6 安装lxml模块[ubuntu14.04 LTS]
    ubuntu14.04 LTS Python IDE专用编辑器PyCharm开发环境搭建
    Git 创建两个“本地分支”协同工作
    关于refs/for/ 和refs/heads/
    Git 多人协作开发的过程
    gerrit_bash_commands.sh
    Ubuntu Eclipse配置Python开发环境
    看看你那张熬完夜的脸
    2016-01-24
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5450496.html
Copyright © 2020-2023  润新知