码迷,mamicode.com
首页 > 其他好文 > 详细

hihocoder #1052 基因工程

时间:2015-04-25 14:54:54      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

传送门:基因工程

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

当然,K<=N/2时,比较简单。下面我着重讲一下当K>N/2,即前K个字符与后K个字符有重叠时,如何思考这个问题。

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

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

S[i] = S[i+N-K]   1 <= i <=K

即“S是以N-K为周期的字符串”。

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

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

满足

S[i] = S[i+N-K]   1 <= i <=K

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

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

对于任意长为N的字符串S

  S[i] = S[N-K+i]  1 <= i <=K,  0 <=K <=N,

  <=> S是某个以N-K为周期的无限长字符串T的子串

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

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

可以通过频数统计求解:

分别统计

1, 1+N-K, 1+2*(N-K), ...

2, 2+N-k, ...

  ....

N-K, N-K+N-K, ...

上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\n", ans);
33     }
34     return 0;
35 }

 

hihocoder #1052 基因工程

标签:

原文地址:http://www.cnblogs.com/Patt/p/4455834.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!