zoukankan      html  css  js  c++  java
  • UVA 140 递归 尝试剪枝ac10ms

    //uva140 AC10ms

    /*刘叔书里说起了剪枝,就想试一下,昨晚一直WA,想看刘叔的代码发现他用的是直接枚举,讲道理我觉得剪枝对条件的筛选也需要时间,不一定快,下面是递归和加入

    剪枝的AC代码,刚才跑了一下变成20ms,不管了吃饭去*/

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    int A[8], g[8][8], num[8];
    int ans[8];
    int vis[8];
    int ch2int[256];
    char int2ch[8];
    int _min;
    int n;
    void dfs( int cur)
    {
     if (cur == n) {//新排列
      int max = 0;
      for(int i=0;i<n;i++)
       for (int j = 0;j < n;j++)
       {
        if (i!=j&&g[A[i]][A[j]] && fabs(i - j) > max)max = (int)fabs(i - j);
       }
      if (max < _min) { 
       _min = max;
       memcpy(ans, A, sizeof(A));
      }
      return;
     }
     for(int i=0;i<n;i++)
      if (!vis[i]) {
       A[cur] = i;
       vis[i] = 1;
       int ok = 1;//假设进行dfs
       for (int i = 0;i <= cur;i++)
       {
        int count = 0, max = 0;
        for(int j=0;j<=cur;j++)
         if (i!= j&&g[A[i]][A[j]]) { 
          count++;
          if (fabs(i - j) > max)max = (int)fabs(i - j);
         }
        if(max>_min
         || (num[i] - count > 0 && num[i] - count + cur - i > _min)//没有这个剪枝20ms
         ) {
         ok = 0;break;
        }
       }
       if (ok)dfs( cur + 1);
       vis[i] = 0;
      }
    }
    char s[205];
    int main(void)
    {
     while (scanf("%s",s)==1 && s[0] != '#') {
      memset(vis, 0, sizeof(vis));
      memset(g, 0, sizeof(g));
      memset(num, 0, sizeof(num));
      _min = 10;
      //printf("%d", 'A');
      //fgets(s, 100, stdin);
      int len = strlen(s);
      n = 0;
      for (char ch = 'A';ch <= 'Z';ch++)
       if (strchr(s, ch) != NULL) {
        ch2int[(int)ch] = n;
        int2ch[n] = ch;
        n++;
       }
      int pre;
      for (int i = 0;i < len;i++)
      {
       char c = s[i];
       //int pre;
       if (c <= 'Z'&&c >= 'A') {
        if (s[i + 1] == ':')pre = ch2int[(int)c];
        else {
         //printf("debug:%d", pre);
         int ne = ch2int[(int)c];
         g[pre][ne] = g[ne][pre] = 1;
         num[pre]++;
    /*这里如果把下一行"num[ne]++;"注释掉,然后没有下面的num[i]除以2,说实话我不知道为什么这样改就WA,这样好像num[i]也能保证小于等于i的相邻结点数?如若看
    过代码知道鄙人错误欢迎指出*/
         num[ne]++;
        }
       }
      }
      //输入有点迷,看起来像是有向表,解析给我的感觉是无向表,无论如何,除以2后num[i]总是小于等于i的相邻节点数
      for (int i = 0;i < n;i++)num[i] /= 2;
      dfs(0);
      for (int i = 0; i < n; i++)
      {
       printf("%c ", int2ch[ans[i]]);
      }
      printf("-> %d
    ", _min);
     }
     return 0;
    }
  • 相关阅读:
    挖矿病毒入侵-分析总结
    Linux查看包依赖关系的神器-repoquery分享
    Elasticsearch 字段为空(null)记录查询
    Python 导数 Elasticsearch 元数据到CSV
    基于docker快速构建MySQL主从复制环境
    Redis环境简单部署(集群/双机)
    FTP 脚本 to Shell脚本&bat脚本&python脚本
    专用服务器模式&共享服务器模式
    CentOS 7安装部署ELK 6.2.4-SUCCESS
    zabbix 数据库迁移变更
  • 原文地址:https://www.cnblogs.com/schsb/p/8036812.html
Copyright © 2011-2022 走看看