【清华集训 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\) 的网格状棋 ...
随机推荐
- 用户数以及psp
小组名称:好好学习 小组成员:林莉 王东涵 胡丽娜 宫丽君 项目名称: 记账本 alpha发布48小时以后用户数如何,是否达到预期目标,为什么,是否需要改进,如何改进(或理性估算). 首先我 ...
- Beta版本发布140字评论
1.飞天小女警组: 礼物挑选工具:系统界面十分新颖,相比于前阶段,增加了账号登陆的功能,并且还根据不同的价位区间添加了礼物的图片,并根据礼物的受欢迎程度添加了top10的功能,并且增加了关于本网站的问 ...
- [转帖] go的import 语法
package 的导入语法写 Go 代码的时经常用到 import 这个命令用来导入包,参考如下: import( "fmt" ) 然后在代码里面可以通过如下的方式调用: fmt. ...
- 【Java并发编程】之八:多线程环境中安全使用集合API
在集合API中,最初设计的Vector和Hashtable是多线程安全的.例如:对于Vector来说,用来添加和删除元素的方法是同步的.如果只有一个线程与Vector的实例交互,那么,要求获取和释放对 ...
- Business Cards UVALive - 4384(画图看图。。)
只能由三种情况 都横着放 都竖着放 横和竖交错放 那就去判断好了... 具体看代码 #include <iostream> #include <cstdio> #inclu ...
- php的数组转为对象
有时候数组要转为对象操作,用对象的指向操作符,有两种方法 方法一: $arr=['a'=>10,'b'=>100,'c'=>'Hello']; $obj=(Object)$arr; ...
- C++运算符重载形式——成员函数or友元函数
运算符重载是C++多态的重要实现手段之一.通过运算符重载对运算符功能进行特殊定制,使其支持特定类型对象的运算,执行特定的功能,增强C++的扩展功能. 运算符重载的我们需要坚持四项基本原则: (1)不可 ...
- IntelliJ IDEA详细配置和使用教程-字体、编码和基本设置
IDEA使用--字体.编码和基本设置 https://blog.csdn.net/frankcheng5143/article/details/50779149 IntelliJ IDEA详细配置和使 ...
- 解题:CQOI 2017 小Q的棋盘
题面 由树的结构我们可以知道,最终要么是连一条(最长的)链都没走完,要么是走了一些点最后走了最长的链.为什么总是说最长的链呢,因为在树上这样走的过程中(最后不要求返回的话)除了一条链都会被走两次,显然 ...
- 解题:JSOI 2008 Blue Mary的战略地图
题面 这大概不算是从零开始的DP学习系列,这不是最大子矩形吗=.= 定义$dp[x][y][xx][yy]$表示第一张地图中右下角为$(x,y)$,第二张地图中右下角为$(xx,yy)$的最大公共子矩 ...