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\n", _min);
 }
 return 0;
}

 

posted on 2017-12-14 11:31  只是个回忆录  阅读(157)  评论(0编辑  收藏  举报

导航