zoukankan      html  css  js  c++  java
  • HDU1560 DNA sequence(迭代加深搜索)

    题意:给你一些字符串(s_0, ...,s_{n-1}),求一个串S,S要把(s_0)(s_{n-1})包括进来,输出S的最短长度

    包括的意思是:对于串(s_i,i=0,...,n, s_i)(S)的最长公共子序列为(s_i)

    一开始的想法是这样的:从前向后遍历每个串,对于每一个串(s_i),求一下(s_0,...s_{i-1})(s_i)的最长公共子序列长度的最大值maxv,然后将总长度sum加上(len(s_i) - maxv),最后输出sum,这个方法乍一看好像很对,用了贪心,但是事实上搞不到最优解...

    思路:正确思路是迭代加深搜索,就是dfs外面套一层循环,用来规定dfs最大深度值,这种方法在找最优解的时候很有用,只要在某一个深度找到了解,那么就是最优解,而且还可以避免在不可能找到解的分支上越走越远(因为限定了深度)

    注意:由于本题时间限制为0.5s,所以还需要剪枝,每一次递归判断一下如果当前递归层数 + 最少还需要递归的层数(当前所有串中剩余比较长度的最大值)> 迭代的最大深度,就说明不行

    另外的话,如果dfs找到答案,就退出循环,直接输出深度d就行了
    假设在限制深度为d时dfs返回1,说明找到了答案,并且答案所在的层数<=d,假设答案所在层数<d, 那么由于是迭代加深搜索,所以一定会在某一个(d_1(<d))的时候就找到了答案,又因为到在(d_1)是dfs返回0,所以矛盾,所以答案所在层数一定是d, 因为每递归一层串长+1,所以答案的长度就是d

    #include<iostream>
    #include<string>
    #include<vector>
    
    using namespace std;
    
    const int N = 10;
    
    char c[] = {'A', 'C', 'G', 'T'};
    vector<string> str;
    int n;
    
    int dfs(int u, int d, int p1[]){
        if(u > d) return 0;
        
        int maxv = 0;
        for(int i = 0; i < n; i ++) maxv = max(maxv, (int) str[i].size() - p1[i]);
        
        if(u + maxv > d) return 0;
        
        for(int i = 0; i < 4; i ++){
            int p2[10], st = 1;
            for(int j = 0; j < n; j ++){
                if(p1[j] >= str[j].size()){
                    p2[j] = p1[j];
                    continue;
                }
                if(str[j][p1[j]] == c[i]){
                    p2[j] = p1[j] + 1;
                }
                else p2[j] = p1[j];
                st = 0;
            }
            if(st || dfs(u + 1, d, p2)) return 1;
        }
        
        return 0;
    }
    
    int main(){
          int t;
          cin >> t;
          while(t --){
              str.clear();
              cin >> n;
              for(int i = 0; i < n; i ++){
                  string s;
                  cin >> s;
                  str.push_back(s);
              }
              
              int d = 0, p[10] = {0};
              while(1){
                  d ++;
                  if(dfs(0, d, p)) break;
              }
              cout << d << endl;
          }
          
          return 0;
    }
    
  • 相关阅读:
    常用网址记录
    css一些兼容问题
    css hack
    js 闭包
    js 继承
    js 实现淘宝放大镜
    css做三角形的方法
    js 轮播效果
    css3特效
    css布局
  • 原文地址:https://www.cnblogs.com/tomori/p/15359488.html
Copyright © 2011-2022 走看看