【清华集训 2017】小Y的地铁 [模拟退火]
小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
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
using namespace std;
typedef long long s64; const int ONE = ;
const int INF = ; int get()
{
int res = , Q = ; char c;
while( (c = getchar()) < || c > )
if(c == '-') Q = -;
if(Q) res = c - ;
while( (c = getchar()) >= && c <= )
res = res * + c - ;
return res * Q;
} int n, num;
int pos[ONE], val[ONE];
int vis[ONE], a[ONE];
int Ans = INF;
struct power {int l, r;} A[ONE]; int x[ONE][ONE], y[ONE][ONE]; void Deal_first()
{
x[][] = x[][] = x[][] = ;
x[][] = x[][] = x[][] = ;
x[][] = x[][] = x[][] = ;
x[][] = x[][] = x[][] = ;
for(int i = ; i <= ; i++) y[i][] = y[i][] = ;
} int Now; int Judge(int pos, int type)
{
int res = Now;
for(int i = pos, j = pos + ; j <= num; j++)
{
if(A[i].r < A[j].l) continue;
if(A[i].r < A[j].r) res -= !x[a[i]][a[j]];
if(A[j].r < A[i].r) res -= !y[a[i]][a[j]];
}
for(int i = , j = pos; i < pos; i++)
{
if(A[i].r < A[j].l) continue;
if(A[i].r < A[j].r) res -= !x[a[i]][a[j]];
if(A[j].r < A[i].r) res -= !y[a[i]][a[j]];
} a[pos] = type; for(int i = pos, j = pos + ; j <= num; j++)
{
if(A[i].r < A[j].l) continue;
if(A[i].r < A[j].r) res += !x[a[i]][a[j]];
if(A[j].r < A[i].r) res += !y[a[i]][a[j]];
}
for(int i = , j = pos; i < pos; i++)
{
if(A[i].r < A[j].l) continue;
if(A[i].r < A[j].r) res += !x[a[i]][a[j]];
if(A[j].r < A[i].r) res += !y[a[i]][a[j]];
} Now = res, Ans = min(Ans, res);
return res;
} double Random() {return (double)rand() / RAND_MAX;}
void SA()
{
if(num == ) return;
double T = num * ;
while(T >= 0.01)
{
int pos = rand() % num + , type = rand() % + ;
int ori = Now, ori_type = a[pos]; int dE = Judge(pos, type) - ori;
if(dE <= || Random() <= exp(-dE / T)) a[pos] = type;
else Judge(pos, ori_type); T *= 0.9993;
}
} void Deal()
{
Ans = INF;
n = get();
for(int i = ; i <= n; i++) a[i] = get(), pos[a[i]] = vis[a[i]] = ;
for(int i = n; i >= ; i--)
if(!pos[a[i]]) pos[a[i]] = i; num = ;
for(int i = ; i <= n; i++)
if(!vis[a[i]] && pos[a[i]] != i)
A[++num] = (power){i, pos[a[i]]}, vis[a[i]] = ; for(int i = ; i <= num; i++)
a[i] = rand() % + ;
Ans = ;
for(int i = ; i <= num; i++)
for(int j = i + ; j <= num; j++)
{
if(A[i].r < A[j].l) break;
if(A[i].r < A[j].r) Ans += !x[a[i]][a[j]];
if(A[j].r < A[i].r) Ans += !y[a[i]][a[j]];
}
Now = Ans;
for(int i = ; i <= ; i++)
SA();
printf("%d\n", Ans);
} int main()
{
Deal_first();
int T = get();
while(T--)
Deal();
}
【清华集训 2017】小Y的地铁 [模拟退火]的更多相关文章
- [清华集训2017]小 Y 和地铁(神奇思路,搜索,剪枝,树状数组)
世界上最不缺的就是好题. 首先考虑暴搜.(还有什么题是从这东西推到正解的……) 首先单独一个换乘站明显没用,只用考虑一对对的换乘站. 那么有八种情况:(从题解偷图) 然后大力枚举每个换 ...
- 【清华集训】小Y和地铁
图已挂,前往luogu 题目: 小 $\rm Y$ 是一个爱好旅行的 $\rm OIer$.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁.她发现每条地铁线路可以看成平面上的一条 ...
- 清华集训2017D2T1 小 Y 和地铁(metro)
题目:https://www.luogu.org/problem/show?pid=P4005 题意:一条线段,给定n个点(n<=44)其中每个点可能对应另外一个点.如果一个点有对应点,那么就要 ...
- [LOJ#2323]「清华集训 2017」小Y和地铁
[LOJ#2323]「清华集训 2017」小Y和地铁 试题描述 小Y是一个爱好旅行的OIer.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁. 她发现每条地铁线路可以看成平面上的 ...
- Loj #2324. 「清华集训 2017」小 Y 和二叉树
Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...
- 【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)
[UOJ#340][清华集训2017]小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划) 题面 UOJ 洛谷 题解 考虑如何暴力\(dp\). 设\(f[i][a][b][c]\)表示当前到了第\(i\) ...
- loj #2325. 「清华集训 2017」小Y和恐怖的奴隶主
#2325. 「清华集训 2017」小Y和恐怖的奴隶主 内存限制:256 MiB时间限制:2000 ms标准输入输出 题目类型:传统评测方式:文本比较 题目描述 "A fight? Co ...
- [LOJ#2324]「清华集训 2017」小Y和二叉树
[LOJ#2324]「清华集训 2017」小Y和二叉树 试题描述 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙 ...
- Loj #2321. 「清华集训 2017」无限之环
Loj #2321. 「清华集训 2017」无限之环 曾经有一款流行的游戏,叫做 *Infinity Loop***,先来简单的介绍一下这个游戏: 游戏在一个 \(n \times m\) 的网格状棋 ...
随机推荐
- jquery 点击弹出层自身以外的任意位置,关闭弹出层
<!--弹出层---> <div class="mask"> <div class="wrap"></div&g ...
- 正确的姿势解决IE弹出证书错误页面
在遇到IE证书问题时,正确的解法是安装证书到受信任的储存区 1.继续浏览此网站 2.进入页面后,点击地址栏的证书错误,查看证书 3.安装,设置安装到受信任的颁发机构 4.OK
- 实测 | 转型微服务,这4大工具谁是API网关性能最优?
转自:http://www.servicemesh.cn/?/article/45 作者:Turgay Çelik 翻译:钟毅(Drew Zhong) 原文:Comparing API Gateway ...
- vue中的数据双向绑定
学习的过程是漫长的,只有坚持不懈才能到达到自己的目标. 1.vue中数据的双向绑定采用的时候,数据劫持的模式.其实主要是用了Es5中的Object.defineProperty;来劫持每个属性的get ...
- PHP面试经常被提到的问题
1. Include 与 require的区别,require和require_once的效率哪个高? PHP在遇到include时就解释一次,如果页面中出现10次include,php就解释10次, ...
- Java中split的对象被特殊字符(.或|)分隔
在Java中,一个String对象被一些特殊字符分隔时,可以使用split()方法,生成一个String[],然后进行其他的操作,就像下面这样: String str = "a1_b1_c1 ...
- STM32CubeMX介绍、下载与安装
一.简介 STM32CubeMX是一个配置STM32代码的工具,它把很多东西封装的比较好,硬件抽象层.中间层.示例代码等.现在ST公司升级和维护的库主要就是STM32CubeMX的HAL库和标准外设库 ...
- P2151 [SDOI2009]HH去散步
题目描述 HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢 ...
- 用Python实现的数据结构与算法:链表
一.概述 链表(linked list)是一组数据项的集合,其中每个数据项都是一个节点的一部分,每个节点还包含指向下一个节点的链接(参考 <算法:C语言实现>). 根据结构的不同,链表可以 ...
- 谷歌发布 Android 8.1 首个开发者预览版,优化内存效率
今晨,谷歌推出了 Android 8.1 首个开发者预览版,此次升级涵盖了针对多个功能的提升优化,其中包含对 Android Go (设备运行内存小于等于 1 GB)和加速设备上对机器学习的全新神经网 ...