• hdu 5677 ztr loves substring 多重背包


    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 178    Accepted Submission(s): 93


    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
     
    Source

    思路:二维费用的

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 105;
    const int INF = 0x3f3f3f3f;
    int Ma[N << 1], Mp[N << 1];
    char s[N];
    int cnt[N];
    
    void manacher(char s[], int len) {
        int l = 0;
        Ma[l++] = '$';
        Ma[l++] = '#';
        for(int i = 0; i < len; ++i)
        {
            Ma[l++] = s[i];
            Ma[l++] = '#';
        }
        Ma[l] = 0;
        int mx = 0, id = 0;
        for(int i = 0; i < l; ++i)
        {
            Mp[i] = mx > i ? min(Mp[2 * id - i], mx - i) : 1;
            while(Ma[ i + Mp[i] ] == Ma[ i - Mp[i] ]) Mp[i]++;
            if(i + Mp[i] > mx) mx = i + Mp[i], id = i;
        }
        for(int i = 0; i < l; ++i) if(Mp[i] > 1) {
            int p;
            if(Mp[i] & 1) p = 2; else p = 1;
            for(int j = p; j < Mp[i]; j += 2) cnt[j]++;
        }
    }
    int dp[N][N];
    void Dp1(int v, int k, int l) {
        for(int i = v; i <= l; ++i)
        for(int j = 1; j <= k; ++j)
        if(dp[i - v][j - 1]) dp[i][j] = 1;
    }
    void Dp2(int v, int num, int k, int l) {
        for(int i = l; i >= v; --i)
        for(int j = k; j >= num; --j)
        if(dp[i - v][j - num]) dp[i][j] = 1;
    }
    
    void to(int x, int k, int l) {
        if(cnt[x] >= k && x * cnt[x] >= l) Dp1(x, k, l);
        else {
            int s = 1, tot = cnt[x];
            while(s < tot) {
                Dp2(x * s, s, k, l);
                tot -= s;
                s <<= 1;
            }
            Dp2(tot * x, tot, k, l);
        }
    }
    bool solve(int k, int l) {
        memset(dp, 0, sizeof dp);
        dp[0][0] = 1;
        for(int i = 1; i <= 100; ++i) if(cnt[i]) to(i, k, l);
        if(dp[l][k]) return true;
        return false;
    }
    int main() {
       // freopen("in", "r", stdin);
        int _; scanf("%d", &_);
        while(_ --) {
            int n, k, l;
            scanf("%d%d%d", &n, &k, &l);
            memset(cnt, 0, sizeof cnt);
            for(int i = 0; i < n; ++i) {
                scanf("%s", s);
                int len = strlen(s);
                manacher(s, len);
            }
            if(solve(k, l)) puts("True");
            else puts("False");
        }
        return 0;
    }
    View Code

    ,且二维都要求恰好装满,那么初始化[0][0]能满足,其它状态都不满足

  • 相关阅读:
    [转载]Oracle查看当前用户权限
    [转载]Oracle查看当前用户权限
    UltraEdit实用技巧
    _splitpath,_makepath分析路径
    [ZT]让你的软件界面更漂亮(1、2)
    [book]程序员修炼之道
    考考你的C++水平
    将*.STL转换成顶点索引格式
    JBuilder 2006 企业完整版
    [book]道法自然
  • 原文地址:https://www.cnblogs.com/orchidzjl/p/5452967.html
Copyright © 2020-2023  润新知