zoukankan      html  css  js  c++  java
  • [loj3526]修改DNA

    如果$a[x..y]$和$b[x..y]$的某种字符数量不同,显然无解

    考虑一个$[x,y]$的排列$p[x..y]$,使得$forall xle ile y,a_{i}=b_{p_{i}}$,即最终要让$i$到$p_{i}$的位置

    建有向边$(i,p_{i})$,由于每一个点入度和出度都为1,即构成若干个环,而一个大小为$l$的环仅需要交换$l-1$次即可,那么总交换次数为$(y-x+1)-$环数

    问题即构造$p_{i}$并最小化交换次数,也即最大化环数

    对于$a_{i}=b_{i}$的位置,令$p_{i}=i$即可,每一个位置都构成一个环

    对于$a_{i} e b_{i}$的位置,仅关心于$(a_{i},b_{i})$这个二元组的个数,假设有$AT$个$(A,T)$、$AC$个$(A,C)$……

    接下来,考虑环的形式,必然是形如$AT$和$TA$的二元组或$AT,CA$和$TC$的三元环

    贪心优先选择前者,由于$a[x..y]$和$b[x..y]$的每种字符数量相同,若$AT$比$TA$多,必然$CA$比$AC$多,由此剩下的部分必然构成若干个三元环

    (关于贪心的正确性,感性理解即可)

     1 #include<bits/stdc++.h>
     2 #include"dna.h"
     3 using namespace std;
     4 #define N 100005
     5 int n,ans,tot[N][3][3],a[3][3];
     6 int change(char c){
     7     if (c=='A')return 0;
     8     if (c=='T')return 1;
     9     return 2;
    10 }
    11 void init(string a,string b){
    12     n=a.length();
    13     for(int i=0;i<n;i++){
    14         memcpy(tot[i+1],tot[i],sizeof(tot[i]));
    15         tot[i+1][change(a[i])][change(b[i])]++;
    16     }
    17 }
    18 int get_distance(int x,int y){
    19     for(int i=0;i<3;i++)
    20         for(int j=0;j<3;j++)a[i][j]=tot[y+1][i][j]-tot[x][i][j];
    21     for(int i=0;i<3;i++){
    22         int s=0;
    23         for(int j=0;j<3;j++)s+=a[i][j]-a[j][i];
    24         if (s)return -1;
    25     }
    26     ans=y-x+1;
    27     for(int i=0;i<3;i++)ans-=a[i][i];
    28     for(int i=0;i<3;i++)
    29         for(int j=i+1;j<3;j++)ans-=min(a[i][j],a[j][i]);
    30     ans-=abs(a[0][1]-a[1][0]);
    31     return ans;
    32 }
    View Code
  • 相关阅读:
    windows任务计划
    PHP创建多级文件夹
    js正则表达式(不断总结中....)
    js随机改变背景颜色
    提高PHP代码质量36计
    PHP中使用Filter进行数据安全过滤
    CSS颜色代码大全
    正则表达式的修饰符
    创建索引视图
    读取xml中的所有文件名
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15001611.html
Copyright © 2011-2022 走看看