zoukankan      html  css  js  c++  java
  • MZOJ #68 基因重组

    题目

    分析

     part 1

    关于这道题,我一直以为切下来的DNA片段可以存起来,可以备用(那这还怎么DP?!)。

    我一直以为insert的必须来自原料串

    于是这道题好难好难(……)

    后来教练告诉我不能存起来

    后来教练告诉我insert的不来自原料串

    笑容逐渐凝固

    我真傻,真的

    part 2

    这道题最大的难点在理解题意上

    这道题的难点大概就在状态表示与初始化了

    状态确定后,方程就好找了

    关于状态,因为copy与cut都可以连续,所以必须存入上一次是否是copy或cut便于连续;

    copy可以翻转,这个也要存下来

    当然还要存下当前的最优方案

    于是状态:

    dp[i][j][0/1/2/3]表示用了原料串的前i个,目标串拼完了第j个的最优方案

    1:表示最后一步为copy且不翻转的最优方案

    2:表示最后一步为copy且要翻转的最优方案

    3:表示最后一步为cut的最优方案

    0:表示最优方案(对最后一步无限制)

    part 3

    状态确定,方程就好写了:

    if(t[j] == s[i]) dp[i][j][1] = min(dp[i-1][j-1][1],dp[i-1][j-1][0]+c1);

    if(t[j] == match(s[i])) dp[i][j][2] = min(dp[i-1][j-1][2],dp[i-1][j-1][0]+c1);

    dp[i][j][3] = min(dp[i-1][j][3],dp[i-1][j][0]+c2);

    dp[i][j][0] = min(dp[i][j][1],min(dp[i][j][2],dp[i][j][3]));

    dp[i][j][0] = min(dp[i][j][0],dp[i][j-1][0]+c3);

    part 4

    O(n2)的复杂度会爆空间,看方程,当前dp[i][][]只与dp[i-1][][]有关,所以滚动i就好

    题解:

    代码

      1 /***************************
      2 User:Mandy.H.Y
      3 Language:c++
      4 Problem:DNA
      5 Algorithm:
      6 Score:
      7 ***************************/
      8 
      9 //注意边界!!! 
     10 
     11 /*
     12 
     13 D[i,j]表示原材料已经去掉了前i个,目标链已经生成了前j个所需的最小花费。
     14 
     15 d[i,j,0]表示使用任意方法达到状态D[i,j]的最少时间,d[i,j,1]与d[i,j,2]表示最后一
     16 次使用正向与反向切割拷贝的方法达到状态D[i,j]的最少时间,d[i,j,3]表示最后一次使用删
     17 除原串的方法达到状态D[i,j]的最少时间。
     18 
     19 
     20 */
     21 
     22 #include<bits/stdc++.h>
     23 
     24 using namespace std;
     25 
     26 const int maxn = 5005;
     27 const int maxt = 20000;
     28 
     29 int c1,c2,c3,sl,tl;
     30 char s[maxn];
     31 char t[maxn];
     32 int dp[3][maxn][5];
     33 
     34 template<class T>inline void read(T &x){
     35     x = 0;bool flag = 0;char ch = getchar();
     36     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
     37     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
     38     if(flag) x = -x;
     39 }
     40 
     41 template<class T>void putch(const T x){
     42     if(x > 9) putch(x / 10);
     43     putchar(x % 10 | 48);
     44 }
     45 
     46 template<class T>void put(const T x){
     47     if(x < 0) putchar('-'),putch(-x);
     48     else putch(x);
     49 }
     50 
     51 void file(){
     52     freopen("DNA.in","r",stdin);
     53     freopen("DNA.out","w",stdout);
     54 }
     55 
     56 void readdata(){
     57     read(c1);read(c2);read(c3);
     58     scanf("%s",s);sl = strlen(s);
     59     scanf("%s",t);tl = strlen(t);
     60 } 
     61 
     62 char match(char a){
     63     if(a == 'T') return 'A';
     64     if(a == 'A') return 'T';
     65     if(a == 'C') return 'G';
     66     if(a == 'G') return 'C';
     67 }
     68 
     69 void work(){
     70     memset(dp,0x3f3f3f3f,sizeof(dp));
     71     dp[0][0][0] = 0;
     72     dp[0][0][3] = c2;//初始化 
     73     int cur = 0;
     74     int ans = 2e9;
     75     
     76     for(int i = 1;i <= tl ; ++ i){
     77         dp[0][i][0] = dp[0][i-1][0]+c3;//不用材料串 
     78     }
     79     ans = dp[0][tl][0];
     80     cur = 1;
     81     for(int i = 0;i < sl; ++ i){
     82         
     83         dp[cur][0][3] = c2;
     84         dp[cur][0][1] = 0x3f3f3f3f;
     85         dp[cur][0][2] = 0x3f3f3f3f;
     86         dp[cur][0][3] = 0x3f3f3f3f;
     87         dp[cur][0][0] = c2;//%%% 
     88         //只删原料串 
     89         for(int j = 1;j <= tl; ++ j){//把j右移一位,便于处理边界 
     90             
     91             dp[cur][j][1] = 0x3f3f3f3f;
     92             dp[cur][j][2] = 0x3f3f3f3f;
     93             dp[cur][j][3] = 0x3f3f3f3f;//初始化 !!! 
     94             
     95             if(t[j-1] == s[i]) dp[cur][j][1] = min(dp[cur^1][j-1][1],dp[cur^1][j-1][0]+c1);
     96             
     97             if(t[j-1] == match(s[i])) dp[cur][j][2] = min(dp[cur^1][j-1][2],dp[cur^1][j-1][0]+c1);
     98             
     99             dp[cur][j][3] = min(dp[cur^1][j][3],dp[cur^1][j][0]+c2);
    100             
    101             dp[cur][j][0] = min(dp[cur][j][1],min(dp[cur][j][2],dp[cur][j][3]));
    102             
    103             dp[cur][j][0] = min(dp[cur][j][0],dp[cur][j-1][0]+c3);
    104             
    105         }
    106         ans = min(ans,dp[cur][tl][0]);
    107         cur ^= 1;
    108     }
    109     put(ans);
    110 }
    111 
    112 int main(){
    113 //    file();
    114     readdata();
    115     work();
    116     return 0;
    117 }
    View Code
    非做顽石不可,哪管他敬仰暗唾
  • 相关阅读:
    转:Windows 7下安装CentOS双系统
    STL学习总结之<迭代器>
    转:linux静态库与动态库
    指向类成员和成员函数的指针
    STL学习总结之<仿函数>
    转:Linux Crontab 定时任务 命令详解
    转: 解决 Redhat 出现”This system is not registered with RHN”更新
    IOS 判断设备屏幕尺寸、分辨率
    IOS 文件管理共通函数整理
    IOS 编译ffmpeg For SDK6.1,模拟器、armv7、armv7s均可使用
  • 原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11410740.html
Copyright © 2011-2022 走看看