$\DeclareMathOperator{\rev}{rev}$

传送门:基因工程

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

当然,$k\le\frac{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$. $\rev(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}$ ($0\le i < t$).
Period of $x$: $x$ has a period of length $t$ iff $x_i = x_i + t$ $(0 \le i < |x| - t)$. When $t\mid |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 基因工程 后写的。看他画的图还是不能完全把握这个问题,我觉得从数学上将问题形式化,寻找能够简化问题的必要条件,对我们分析问题极有帮助,也是一种科学的思维方式。我们即使不画图也能透彻地分析这个问题,相反只看李舜阳的图而不借助形式化的推导仍是糊里糊涂。

 #include<bits/stdc++.h>
using namespace std;
const int MAX_N=1e3+;
char s[MAX_N];
const char* item="ACGT";
int main(){
//freopen("in", "r", stdin);
int T, K, N, rep, ans, maxi, cnt[]; //A, C, G, T
scanf("%d", &T);
while(T--){
scanf("%s%d", s+, &K);
N=strlen(s+);
rep=N-K;
ans=;
for(int i=; i<=rep; i++){
memset(cnt, , sizeof(cnt));
for(int j=i; j<=N; j+=rep){
for(int k=; k<; k++){
if(s[j]==item[k]){
cnt[k]++;
break;
}
}
}
maxi=;
for(int j=; j<; j++){
maxi=max(maxi, cnt[j]);
ans+=cnt[j];
}
ans-=maxi;
}
printf("%d\n", ans);
}
return ;
}

hihocoder #1052 基因工程的更多相关文章

  1. hihocoder #1052 : 基因工程(字符串处理 + 找规律 )

    #1052 : 基因工程 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho正在进行一项基因工程实验.他们要修改一段长度为N的DNA序列,使得这段DNA上最前面 ...

  2. hihoCoder 1052 基因工程 最详细的解题报告

    题目来源:基因工程 解题思路:假设基因序列长度为N,则需要计算基因序列前K个和后K个相同所需要的最少改变次数sum. 假设基因序列为 ATACGTCT (即M=8),K=6:interval=M-K= ...

  3. HihoCoder#1052:基因工程

    HihoCoder#1052:基因工程 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho正在进行一项基因工程实验.他们要修改一段长度为N的DNA序列,使得这段 ...

  4. 【HIHOCODER 1052 】基因工程(贪心)

    链接 问题描述 小Hi和小Ho正在进行一项基因工程实验.他们要修改一段长度为N的DNA序列,使得这段DNA上最前面的K个碱基组成的序列与最后面的K个碱基组成的序列完全一致. 例如对于序列"A ...

  5. [HIHO1052]基因工程(找规律)

    题目链接:http://hihocoder.com/problemset/problem/1052 题意:中文题面,就是修改其中几个字符,使得[0,k-1]和[n-k,n-1]的字符相同. 会发现一个 ...

  6. AC日记——地鼠游戏 codevs 1052

    1052 地鼠游戏  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 王钢是一名学习成绩优异的学生,在平 ...

  7. codevs 1052 地鼠游戏

    1052 地鼠游戏 http://codevs.cn/problem/1052/ 题目描述 Description 王钢是一名学习成绩优异的学生,在平时的学习中,他总能利用一切时间认真高效地学习,他不 ...

  8. hihocoder -1121-二分图的判定

    hihocoder -1121-二分图的判定 1121 : 二分图一•二分图判定 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 大家好,我是小Hi和小Ho的小伙伴Net ...

  9. Hihocoder 太阁最新面经算法竞赛18

    Hihocoder 太阁最新面经算法竞赛18 source: https://hihocoder.com/contest/hihointerview27/problems 题目1 : Big Plus ...

随机推荐

  1. 什么是API

    我们从API的功能.分类.设计.实现.用户来看什么是API. API是应用程序组件之间通信的接口 --wiki:Application Programming Interface In compute ...

  2. <实训|第五天>通过搭建NFS,FTP实现共享文件附Vim脚本游戏

    先说个事情:我周末是不更新这个系列教程的,不过其他内容的会更新,我周末就整理这一周的各种内容到我的微信公众号中,提供给大家! 期待已久的linux运维.oracle"培训班"终于开 ...

  3. 【NDK开发】android-ndk r10环境搭建

    1)打开Android开发者的官网http://developer.android.com/找到Develop点击.如果页面打不开,通过代理来访问. 2)进入后再点击Tools 3)进入后在左侧找到N ...

  4. js的单引号,双引号,转移符

    这里我们看到想在style后边在插入一个样式的变量,data.cssSytle.a是做边和邮编都是"",并且没有转移符

  5. eclipse汉化全程

    在开始之前我说一下我的环境,eclipse版本eclipse-java-indigo-SR2-win32-x86_64,操作系统Win7,但是这个基本上没有影响.红字的那个注意一下,在下面需要根据这个 ...

  6. Stem函数绘图

    stem(n,x,'filled');第三个参数是绘图的样式,filled就是填充,将圆圈填充. Stem函数绘图各种不同的绘图函数分别适用于不同的场合,使用“stem”绘制针状图最简单,从附录中提供 ...

  7. Android无线调试及手机设备与PC同屏工具——Chrome插件Vysor

    我们平时用手机调试时,经常是手不离机,以前可以下载个jar包能把手机屏映射到电脑桌面,但是运行比较卡,后来就放弃了,再之,手机接数据线有时也不太方便 ,pc与手机(连wifi)如处同一网段,就可以通过 ...

  8. eclipse汉化

    一.准备工作: 1.eclipse点击help——about eclipse查看软件版本,如图: 2.登录官网语言包下载地址:http://www.eclipse.org/babel/download ...

  9. java中的hashSet和Treeset的分析

    hashset中的元素 treeset中的元素要实现comparable接口

  10. editplus-使用正则表达式替换每行首字母和尾字母

    打开EditPlus,输入多行数据,快捷键ctrl+h 打开替换窗口,选择“正则表达式”替换 行首批量添加   查找"^" 替换为“我是行首aaa” 行尾批量添加   查找&quo ...