zoukankan      html  css  js  c++  java
  • #3314. constructive

    题目描述

    JohnCheng最近沉迷几何,导致走火入魔,于是打算搞下string来缓解压力。他有一张草稿纸,最开始什么都没有(可以视为有一个空串)。每一步他可以花费 $a$ 时间在当前字符串后面加入任意一个字符,也可以花费 $b imes |S|$ (S为当前字符串)的时间把S抄一遍放在S前面。

    旁边的Worldwide_D正苦于一道字符串毒瘤题,他获得了一个数据点,数据点里有一个长度不大于 $10^6$ 的字符串。他把字符串发给JohnCheng,问他至少能在多长时间内构造出这个字符串。

    JohnCheng:水题一道。然后开始睡觉,并把问题交给了你。

    数据范围

    $∣S∣≤10 ^6 ,1≤b<a≤10 ^5$

    题解

    考虑 $dp$ , $f_i$ 表示构造好了前 $i$ 个字符的最小代价,则首先 $f_i=f_{i-1}+a$

    然后如果 $i$ 是偶数并且 $[1.frac{i}{2}]$ 和 $[frac{i}{2}+1,i]$ 的字符串相同的话,则有 $f_i=min(f_i,f_{frac{i}{2}}+b imes frac{i}{2})$ ,判断相同就用哈希判断

    效率: $O(|S|)$

    代码

    #include <bits/stdc++.h>
    #define LL long long
    #define U unsigned LL
    using namespace std;
    const int N=1e6+5;
    const U K=793999;
    int a,b,n;char s[N];
    LL f[N];U h[N],k[N];
    U H(int l,int r){
        return h[r]-h[l-1]*k[r-l+1];
    }
    int main(){
        scanf("%s%d%d",s+1,&a,&b);
        n=strlen(s+1);k[0]=1;
        for (int i=1;i<=n;i++)
            k[i]=k[i-1]*K,h[i]=h[i-1]*K+s[i];
        for (int i=1;i<=n;i++){
            f[i]=f[i-1]+a;
            if (!(i&1) && H(1,i>>1)==H((i>>1)+1,i))
                f[i]=min(f[i>>1]+1ll*b*(i>>1),f[i]);
        }
        return printf("%lld
    ",f[n]),0;
    }
  • 相关阅读:
    include包含文件查找的顺序
    cookie知多少
    关于“异步可插协议”(About Asynchronous Pluggable Protocols(APPs))
    win7+vs2010下编译chrome
    chrome命令行参数
    头文件预编译
    IBindStatusCallback 状态码
    DEP相关
    调试子进程
    windbg 调试
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/11326965.html
Copyright © 2011-2022 走看看