zoukankan      html  css  js  c++  java
  • hihocoder #1052 基因工程

    $DeclareMathOperator{ ev}{rev}$

    传送门:基因工程 

    这道题拖了好久,一直没有清晰的思路。

    当然,$klefrac{n}{2}$ 时,比较简单。下面我着重讲一下当 $k>frac{n}{2}$ ,即前 $k$ 个字符与后 $k$ 个字符有重叠时,如何思考这个问题。

    为了便于分析,我们把题目要求形式化成如下的数学表示

    假设修改后的字符串为 $S$ ,字符串长度为 $n$ ,则 $S$ 满足

    [S_i = S_{i+n-k} qquad   1 le i le k ]

    即“$S$是以$n-k$为周期的字符串”。

    这样讲对吗?我们回忆一下数学上周期函数的概念,不难发现这个说法不确切,一个有周期性的字符串是无限长的。

    为了消除这种数学上的不严格,我们换一种说法

    满足

    [S_i = S_{i+n-k} qquad  1 le i le k]

    且长为$n$的字符串$S$,必定是某个以 $n-k$ 为周期的无限长字符串 $T$ 的子串

    至此我们找到了一个将问题大大简化了的必要条件,显然这个命题反过来也成立。因而有

    对于任意长为 $n$ 的字符串 $S$

    $S_i = S_{n-k+i}  qquad 1 le i le k, quad  0 le k le n,$

      $iff$ $S$ 是某个以 $n-k$ 为周期的无限长字符串 $T$ 的子串

    UPDATE (2019/5/16)

    另一道跟周期串有关的字符串构造题,CF1158B The minimal unique substring

    $mathsf{UPD (2018/12/27)}$

    多年以后又遇到一个类似的问题,CF1081H Palindromic Magic,想起这篇旧文。

    作者(fjzzq2002)在题解中也定义了周期串,把我所谓「$S$ 是某个以 $t$ 为周期的无限长字符串 $T$ 的子串」径称为「$S$ 以 $t$ 为周期($S$ has a period of length $t$)」。

    现把题解中的一些术语和定义摘录在此。

    Some conventions and symbols:All indices of strings start from zero. $|x|$ denotes length of string $x$. $ ev(x)$ stands for the reverse of string $x$. $xy$ stands for concatenation of $x$ and $y$. $x^{a}$ stands for concatenation of $a$ copies of $x$ (e.g. $x =$ 'ab', $x^2 =$ 'abab'). $x[a, b]$ stands for the substring of $x$ starting and ending from the $a$-th and $b$-th character. (e.g. 'abc'$[1, 2] =$ 'bc')
     
    Border of $x$: strings which are common prefix and suffix of $x$. Formally, $x$ has a border of length $t$ ($x[0, t - 1]$) iff $x_i = x_{|x| - t + i}$ ($0le i < t$).
    Period of $x$: $x$ has a period of length $t$ iff $x_i = x_i + t$ $(0 le i < |x| - t)$. When $tmid |x|$ we also call $t$ a full period. From the formulas it's easy to see $x$ has a period of length $t$ iff $x$ has a border of length $|x| - t$, ($ 1 le t le |x|$).

    问题转化为:求将一个字符串 $S$ 转化为某个以 $n-k$ 为周期的无限长字符串 $T$ 的子串,所需的最少更改次数。

    这个问题思考起来可比原问题清楚多了,而且至此我们已经把开头说到的两种情况统一起来了

    可以通过频数统计求解:

    分别统计

    [1, 1+n-k, 1+2(n-k), dots ]

    [2, 2+n-k, dots]

    [cdots]

    [n-k, n-k+n-k, dots]

    上A, G, C, T出现的频数,将其改成频数最大的那个字符,这样所需的总改动次数就是答案。

    P.S. 这篇随笔是我看了李舜阳hihoCoder #1052 基因工程写的。看他画的图还是不能完全把握这个问题,我觉得从数学上将问题形式化,寻找能够简化问题的必要条件,对我们分析问题极有帮助,也是一种科学的思维方式。我们即使不画图也能透彻地分析这个问题,相反只看李舜阳的图而不借助形式化的推导仍是糊里糊涂。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAX_N=1e3+10;
     4 char s[MAX_N];
     5 const char* item="ACGT";
     6 int main(){
     7     //freopen("in", "r", stdin);
     8     int T, K, N, rep, ans, maxi, cnt[4]; //A, C, G, T
     9     scanf("%d", &T);
    10     while(T--){
    11         scanf("%s%d", s+1, &K);
    12         N=strlen(s+1);
    13         rep=N-K;
    14         ans=0;
    15         for(int i=1; i<=rep; i++){
    16             memset(cnt, 0, sizeof(cnt));
    17             for(int j=i; j<=N; j+=rep){
    18                 for(int k=0; k<4; k++){
    19                     if(s[j]==item[k]){
    20                         cnt[k]++;
    21                         break;
    22                     }
    23                 }
    24             }
    25             maxi=0;
    26             for(int j=0; j<4; j++){
    27                 maxi=max(maxi, cnt[j]);
    28                 ans+=cnt[j];
    29             }
    30             ans-=maxi;
    31         }
    32         printf("%d
    ", ans);
    33     }
    34     return 0;
    35 }
  • 相关阅读:
    67. Add Binary
    66. Plus One
    64. Minimum Path Sum
    63. Unique Paths II
    How to skip all the wizard pages and go directly to the installation process?
    Inno Setup打包之先卸载再安装
    How to change the header background color of a QTableView
    Openstack object list 一次最多有一万个 object
    Openstack 的 Log 在 /var/log/syslog 里 【Ubuntu】
    Git 分支
  • 原文地址:https://www.cnblogs.com/Patt/p/4455834.html
Copyright © 2011-2022 走看看