博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【清华集训 2017】小Y的地铁 [模拟退火]
阅读量:6606 次
发布时间:2019-06-24

本文共 3533 字,大约阅读时间需要 11 分钟。

小Y的地铁

Time Limit: 50 Sec  Memory Limit: 256 MB

Description

 

Input

  

Output

  对于每组输入数据,输出一行一个整数,表示除掉这 n 个换乘站之外,最少有几个换乘站。

Sample Input

  4

  4
  1 2 1 2
  8
  1 2 3 4 1 2 3 4
  5
  5 4 3 3 5
  8
  1 2 3 4 1 3 2 4

Sample Output

  0

  0
  0
  1

HINT

  n <= 44

Solution

  首先,答案显然只和几个区域的连通状态有关,那么我们可以写出四种本质不同的方案。(即下图中被线分开的六块)。

  

  我们可以考虑,对于一条线,其他线(显然仅有 部分相交完全相交 两种)造成的贡献。打出表来,上图是不会造成交点的线段种类

  既然知道了这个,我们的复杂度显然可以做到 O(4 ^ (n / 2))。还是不足以通过,怎么办呢?

  模拟退火大法好!

Code

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 using namespace std; 10 typedef long long s64; 11 12 const int ONE = 105; 13 const int INF = 2147483640; 14 15 int get() 16 { 17 int res = 1, Q = 1; char c; 18 while( (c = getchar()) < 48 || c > 57) 19 if(c == '-') Q = -1; 20 if(Q) res = c - 48; 21 while( (c = getchar()) >= 48 && c <= 57) 22 res = res * 10 + c - 48; 23 return res * Q; 24 } 25 26 int n, num; 27 int pos[ONE], val[ONE]; 28 int vis[ONE], a[ONE]; 29 int Ans = INF; 30 struct power { int l, r;} A[ONE]; 31 32 int x[ONE][ONE], y[ONE][ONE]; 33 34 void Deal_first() 35 { 36 x[1][2] = x[1][4] = x[1][5] = 1; 37 x[2][1] = x[2][3] = x[2][6] = 1; 38 x[3][1] = x[3][3] = x[3][6] = 1; 39 x[4][2] = x[4][4] = x[4][5] = 1; 40 for(int i = 1; i <= 4; i++) y[i][1] = y[i][2] = 1; 41 } 42 43 int Now; 44 45 int Judge(int pos, int type) 46 { 47 int res = Now; 48 for(int i = pos, j = pos + 1; j <= num; j++) 49 { 50 if(A[i].r < A[j].l) continue; 51 if(A[i].r < A[j].r) res -= !x[a[i]][a[j]]; 52 if(A[j].r < A[i].r) res -= !y[a[i]][a[j]]; 53 } 54 for(int i = 1, j = pos; i < pos; i++) 55 { 56 if(A[i].r < A[j].l) continue; 57 if(A[i].r < A[j].r) res -= !x[a[i]][a[j]]; 58 if(A[j].r < A[i].r) res -= !y[a[i]][a[j]]; 59 } 60 61 a[pos] = type; 62 63 for(int i = pos, j = pos + 1; j <= num; j++) 64 { 65 if(A[i].r < A[j].l) continue; 66 if(A[i].r < A[j].r) res += !x[a[i]][a[j]]; 67 if(A[j].r < A[i].r) res += !y[a[i]][a[j]]; 68 } 69 for(int i = 1, j = pos; i < pos; i++) 70 { 71 if(A[i].r < A[j].l) continue; 72 if(A[i].r < A[j].r) res += !x[a[i]][a[j]]; 73 if(A[j].r < A[i].r) res += !y[a[i]][a[j]]; 74 } 75 76 Now = res, Ans = min(Ans, res); 77 return res; 78 } 79 80 double Random() { return (double)rand() / RAND_MAX;} 81 void SA() 82 { 83 if(num == 0) return; 84 double T = num * 2; 85 while(T >= 0.01) 86 { 87 int pos = rand() % num + 1, type = rand() % 4 + 1; 88 int ori = Now, ori_type = a[pos]; 89 90 int dE = Judge(pos, type) - ori; 91 if(dE <= 0 || Random() <= exp(-dE / T)) a[pos] = type; 92 else Judge(pos, ori_type); 93 94 T *= 0.9993; 95 } 96 } 97 98 void Deal() 99 {100 Ans = INF;101 n = get();102 for(int i = 1; i <= n; i++) a[i] = get(), pos[a[i]] = vis[a[i]] = 0;103 for(int i = n; i >= 1; i--)104 if(!pos[a[i]]) pos[a[i]] = i;105 106 num = 0;107 for(int i = 1; i <= n; i++)108 if(!vis[a[i]] && pos[a[i]] != i)109 A[++num] = (power){i, pos[a[i]]}, vis[a[i]] = 1;110 111 for(int i = 1; i <= num; i++)112 a[i] = rand() % 4 + 1; 113 Ans = 0;114 for(int i = 1; i <= num; i++)115 for(int j = i + 1; j <= num; j++)116 {117 if(A[i].r < A[j].l) break;118 if(A[i].r < A[j].r) Ans += !x[a[i]][a[j]];119 if(A[j].r < A[i].r) Ans += !y[a[i]][a[j]];120 }121 Now = Ans;122 for(int i = 1; i <= 10; i++)123 SA();124 printf("%d\n", Ans);125 }126 127 int main()128 {129 Deal_first();130 int T = get();131 while(T--)132 Deal();133 }
View Code

 

转载于:https://www.cnblogs.com/BearChild/p/8119082.html

你可能感兴趣的文章
Redis 与 数据库处理数据的两种模式
查看>>
VUE2中axios的使用方法
查看>>
assert 断言
查看>>
CS 229 notes Supervised Learning
查看>>
2018.10.27-dtoj-3996-Lesson5!(johnny)
查看>>
DataTable转换成json字符串
查看>>
iOS网络协议----HTTP/TCP/IP浅析
查看>>
ubuntu 12.04 安装 redis
查看>>
IOS_CGRect
查看>>
Sql Server中不常用的表运算符之APPLY(1)
查看>>
【DM642】ICELL Interface—Cells as Algorithm Containers
查看>>
linux所有命令失效的解决办法
查看>>
力扣算法题—085最大矩阵
查看>>
svs 在创建的时候 上传文件夹 bin obj 这些不要提交
查看>>
mysql-用命令导出、导入表结构或数据
查看>>
Tinkphp
查看>>
EntityFrameworkCore 一对一 && 一对多 && 多对多配置
查看>>
How to temporally disable IDE tools (load manually)
查看>>
Vue.js学习 Item4 -- 数据双向绑定
查看>>
几种排序方式的java实现(01:插入排序,冒泡排序,选择排序,快速排序)
查看>>