zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    命令模式
    js代理模式,处理缓存
    js设计模式之策略模式
    查看并修改签名证书keystore的密码,alias别名等相关参数
    【fiddler】配置代理后个别app连不上网的问题
    使用Fiddler域名过滤、断点、小技巧绕过前端验证
    App上架各大应用市场的地址及操作方法
    获取APK获取APK证书MD5、SHA1、SHA256等秘钥
    Python一切皆对象
    WEB基础之布局与定位
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5450496.html
Copyright © 2011-2022 走看看