zoukankan      html  css  js  c++  java
  • Atcoder CODE FESTIVAL 2017 qual C D

    题目链接

    题意

    给定一个字符串(长度(leq 2e5)),将其划分成尽量少的段,使得每段内重新排列后可以成为一个回文串。

    题解

    分析

    每段内重新排列后是一个回文串( ightarrow)该段内至多只有一个字符出现过奇数次

    考虑哈希到一个(26)位的(01)串,出现过奇数次的元素位置上的值为(1),否则为(0).

    于是可以继续往下推:( ightarrow)该段的哈希值为(0)或者是(2)的幂次。

    转化

    于是问题转化为:将字符串切割成尽量少的若干段,使得每段的哈希值均满足为(0)或者是(2)的幂次

    预处理异或前缀和可以(O(1))算得每段的哈希值。

    问题至此一个很显然的做法就是(O(n^2))(dp),然而显然是无法承受的。

    对dp形式的思考

    我们来考虑一下原先想写的(dp)的形式:

    [dp[i]=min_{j<i,ok(j+1,i)}{dp[j]}+1 ]

    这里的(ok(j+1,i))指的是(s[j+1..i])一段的哈希值满足要求。

    仔细思考一下,这里有两个约束条件,

    1. (j<i)
    2. (ok(j+1,i))

    我们常规的思路是拿第一个条件去循环,然后判断第二个条件是否被满足。
    然而在这里,对于给定的(i),有(i-1)(j)满足第一个条件,而只有(leq 27)(j)满足第二个条件。
    更优的考虑是拿第二个条件去循环。

    O(n)-dp

    什么叫做拿第二个条件去循环呢?

    意思是我们直接找到那个(h[j]),它和(h[i])异或起来的值满足条件。

    由异或的性质,(h[i]oplus h[j]=powerleftrightarrow h[i]oplus power=h[j])

    所以,我们应该存的信息有:

    1. (dp[x])代表哈希值为(x)的最少切割次数
    2. (opt[i])代表([1..i])段最少的切割次数

    则显然转移有$$opt[i]=min{dp[h[i]oplus mask]}+1$$$$dp[x]=min(dp[x],opt[i])$$

    官方题解

    Code

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define maxn 200010
    using namespace std;
    typedef long long LL;
    char s[maxn];
    int opt[maxn], h[maxn];
    int main() {
        scanf("%s", s+1);
        int len = strlen(s+1);
        for (int i = 1; i <= len; ++i) h[i] = h[i-1] ^ (1<<(s[i]-'a'));
        map<int, int> dp;
        for (int i = 1; i <= len; ++i) {
            opt[i] = (!h[i] || dp[h[i]]) ? dp[h[i]] : inf;
            int mask = 1;
            for (int j = 0; j < 26; ++j) {
                if ((h[i]^mask) == 0 || dp[h[i]^mask]) opt[i] = min(opt[i], dp[h[i]^mask]);
                mask <<= 1;
            }
            ++opt[i];
            if (!dp[h[i]] && h[i]) dp[h[i]] = opt[i];
            else dp[h[i]] = min(dp[h[i]], opt[i]);
        }
        printf("%d
    ", opt[len]);
        return 0;
    }
    
    
  • 相关阅读:
    AppCan打包问题
    Layui数据表格模型
    Layui关闭弹出层并刷新父窗口
    spring boot重启后图片不见
    MySQL数据库创建时间和更新时间错乱问题
    Spring Boot解决无法访问图片的问题
    Spring Boot解决无法访问图片的问题
    reload() 方法用于重新加载当前文档。配合Ajax异步请求。
    Layui数据表格的接口数据请求方式为Get
    时间格式注解
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/7722578.html
Copyright © 2011-2022 走看看