• uva 11212


    由于编辑的特殊性,只要没达到升序这个条件就可以永远不停的搜下去,最特别的还是那些的错误的路径,也就是说假如一开始就选择了错误的剪切方式,之后这条错误的路会一直往后延伸。。。

    所以采用IDA*解法,IDA*相比与普通的dfs或bfs,多了一个估值函数,比如我从这一层到第n层,每层最多能干多少活,假如剩下的活到第n层怎么都做不完,就不要往下搜了。像这道题,每层最多有三个数字的后缀改变,也就是说最多能使三个数字的后继正确。

    /*
    重要的注意事项:
    flag必须是全局变量:要对全部的回溯步骤造成影响
    m数组必须是临时变量:只存这次,不影响上次
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int a[11],n;
    inline void cat(int *c,int j,int i,int k)
    {
        int v[11],top=0;
        for(int x=0;x<n;x++)
        {
          if(x==k)
          {
              for(int y=j;y<=j+i;y++)
              {
                  v[top++]=c[y];
              }
          }
          if(x>=j&&x<=j+i) continue;
          v[top++]=c[x];
        }
        memcpy(c,v,sizeof(int)*n);
    }
    int flag;  //终止回溯标志
    bool dfs(int cur,int depth,int *c)
    {
        if(flag==1) return false;
        if(flag==2) return true;
        int h=0,fi=0;
        for(int i=0;i<n;i++)
        {
            fi=0;
            for(int j=i+1;j<n;j++)
            {
                if(c[j]<c[i]) {fi=1;break;}
            }
            if(fi) h++;
        }
        if(h+3*cur>3*depth) return false; //估值剪枝,cur亦可代表已完成的层数
        if(cur==depth)
        {
            int ff=0;
            for(int i=0;i<n;i++)
            {
                for(int j=i+1;j<n;j++)
                {
                    if(c[j]<c[i]) {ff=1;break;}
                }
                if(ff) break;
            }
            flag=1;
            if(!ff) {flag=2;return true;}
            return false;
        }
        int m[11];  //存储原态数组
        memcpy(m,c,sizeof(int)*n);
        for(int i=0;i<=n-1;i++)
        {
            for(int j=1;j<=n-i;j++)
            {
                for(int k=0;k<j;k++)
                {
                    if(j+i>=n) break;
                    cat(c,j,i,k);
                    if(dfs(cur+1,depth,c))  return true;
                    memcpy(c,m,sizeof(int)*n);
                }
            }
        }
        return false;
    }
    int main()
    {
        int ca=0;
        for(;scanf("%d",&n),n!=0;)
        {
            for(int i=0;i<n;i++)
            {
                scanf("%d",&a[i]);
            }
            int ans=0;
            for(int i=0;;i++)
            {
                flag=0;
                if(dfs(0,i,a)) {ans=i;break;}
            }
            printf("Case %d: %d
    ",++ca,ans);
        }
        return 0;
    }
  • 相关阅读:
    Flare3D游戏特效教程:火拳阿宝
    AS3:物体的运动
    Away3D基础教程(三):三维世界的灯光
    代码库工具:SVN
    磨刀不误砍柴工:取巧而已
    可视化组件:Swing JComponent
    软件简单升级方式:文件覆盖
    代码库工具:CVS
    多字符串查找算法:kmp与step
    格式化文本支持:JTextPane
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/5469960.html
Copyright © 2020-2023  润新知