zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    【bzoj题解】2186 莎拉公主的困惑
    【算法学习】整体二分
    【算法学习】【洛谷】cdq分治 & P3810 三维偏序
    【比赛游记】NOIP2017游记
    【0】如何在电脑中使用多个python版本【python虚拟环境配置】
    Mysql 安装服务无法启动解决方案与使用的一般使用指令
    4-urllib库添加代理,添加请求头格式 模板
    3-urllib的post请求方式
    02-urllib库的get请求方式
    01-urllib库添加headers的一般方法
  • 原文地址:https://www.cnblogs.com/zqq123/p/5524466.html
Copyright © 2011-2022 走看看