• bzoj4606 DNA


    题意有点复杂,就自己去看吧。

    题解   

    f[i][j][k]表示第i为,为-j范式,当前位为k的方案数,从后往前dp一遍。

    然后再贪心的从前往后填数。但注意当前填的数已经是-cur范式,计算方案的时候要用k-cur来算。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 #define maxn 100020
     7 
     8 typedef long long ll;
     9 ll f[maxn][11][4],R;
    10 int mp[200],a[maxn],ans[maxn];
    11 int n,k;
    12 char ch[maxn],re[5];
    13 
    14 void init(){
    15     if ( a[n] == 5 ){
    16         for (int l = 0 ; l <= 3 ; l++){
    17             for (int i = 1 ; i <= k ; i++){
    18                 f[n][i][l] = 1;
    19             }
    20         }
    21     }
    22     else{
    23         for (int i = 1 ; i <= k ; i++)f[n][i][a[n]] = 1; 
    24     }
    25     for (int i = n - 1 ; i ; i--){
    26         if ( a[i] < 5 ){
    27             for (int j = 1 ; j <= k ; j++){
    28                 for (int l = 0 ; l <= 3 ; l++){
    29                     if ( a[i] >= l ) f[i][j][a[i]] += f[i + 1][j][l]; //如果有这种转移就不能在用f[i + 1][j - 1][l]在更新了。因为f[i + 1][j][l]已经包含了它的方案数,否则会算重
    30                     else f[i][j][a[i]] += f[i + 1][j - 1][l];
    31                 }
    32             }
    33         }
    34         else{
    35             for (int l = 0 ; l <= 3 ; l++){
    36                 for (int j = 1 ; j <= k ; j++){
    37                     for (int p = 0 ; p <= 3 ; p++){
    38                         if ( l >= p ) f[i][j][l] += f[i + 1][j][p];
    39                         else f[i][j][l] += f[i + 1][j - 1][p];
    40                     }
    41                 }
    42             }
    43         }
    44     }
    45 /*    for (int i = 1 ; i <= n ; i++)
    46        for (int l = 0 ; l <= 3 ; l++)    
    47         for (int j = 1 ; j <= k ; j++){
    48             f[i][j][l] += f[i][j - 1][l];
    49         }*/
    50 }
    51 void solve(){
    52     int cur = 1;
    53     ans[0] = 5;
    54     for (int i = 1 ; i <= n ; i++){
    55         if ( a[i] == 5 ){
    56             ll sum[4];
    57             for (int l = 0 ; l <= 3 ; l++){
    58                 if ( ans[i - 1] < l ) sum[l] = f[i][k - cur][l];
    59                 else sum[l] = f[i][k - cur + 1][l];    
    60             }
    61             for (int l = 3 ; l >= 0 && R > 0 ; l--){
    62                 ans[i] = l , R -= sum[l];
    63             }
    64             R += sum[ans[i]];
    65             if ( ans[i - 1] < ans[i] ) cur++;
    66         }    
    67         else{
    68             ans[i] = a[i];
    69             if ( ans[i - 1] < ans[i] ) cur++;
    70         }
    71     }
    72     for (int i = 1 ; i <= n ; i++) printf("%c",re[ans[i]]);
    73     printf("
    ");
    74 }
    75 int main(){
    76     freopen("input.txt","r",stdin);
    77     mp['A'] = 3 , mp['C'] = 2 , mp['G'] = 1 , mp['T'] = 0 , mp['N'] = 5;
    78     re[3] = 'A' , re[2] = 'C' , re[1] = 'G' , re[0] = 'T';
    79     scanf("%d %d %lld",&n,&k,&R);
    80     scanf("%s",ch + 1);
    81     for (int i = 1 ; i <= n ; i++) a[i] = mp[(int)ch[i]];
    82     init();
    83     solve();
    84 }
  • 相关阅读:
    [转]Linux中用编译的Zlib库替换系统自带的
    [转]Leptonica在VS2010中的编译及简单使用举例
    我的tesseract学习记录
    [转]在VS2010下编译和使用tesseract_ocr
    [转]图像resize
    JVM基础知识(摘抄整理)
    JVM运行时数据内存区和指令集(摘抄整理)
    JMM For Object Size(摘抄整理)
    JMM课程小结(摘抄整理)
    Class的加载过程
  • 原文地址:https://www.cnblogs.com/zqq123/p/5524466.html
Copyright © 2020-2023  润新知