[返回模拟退火略解]

题目描述

在一个 n×mn\times mn×m 的矩阵中,每个点都染了一种颜色(只能是 [1,c][1,c][1,c] 中的一种),求一种方案,使得相邻异色点对数最小。

Solution 3936\text{Solution 3936}Solution 3936

这是一道好题。正所谓代码五分钟,调参两百年。

随机一个矩阵作为初始矩阵。每次降温时尝试交换两个随机元素,判断交换后是否更优。详见代码。

对于每次交换,更新 calccalccalc 函数可以在 O(1)O(1)O(1) 中完成(提示:一个元素仅能与其上下左右相邻的元素产生贡献,仅更新交换的两个元素即可)。这部分请读者自行完成推导。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm> #define reg register int n,m,c;
int p[60];
struct node{
int a[30][30];
}o,ans;
int answ=0x3f3f3f3f; int calc(node a){
int cnt=0;
for(reg int i=1;i<=n;++i)
for(reg int j=1;j<=m;++j){
if(i>=2&&a.a[i][j]!=a.a[i-1][j]) ++cnt;
if(i<=n-1&&a.a[i][j]!=a.a[i+1][j]) ++cnt;
if(j>=2&&a.a[i][j]!=a.a[i][j-1]) ++cnt;
if(j<=n-1&&a.a[i][j]!=a.a[i][j+1]) ++cnt;
}
return cnt/2;
}
void SA(){
double t=1.0;
while(t>1e-15){
node no=ans;
int x1,y1,x2,y2,tt;
do{
x1=rand()%n+1;
y1=rand()%m+1;
x2=rand()%n+1;
y2=rand()%m+1;
}while(x1==x2&&y1==y2);
tt=no.a[x1][y1];no.a[x1][y1]=no.a[x2][y2];no.a[x2][y2]=tt;
int nw=calc(no);
int delta=nw-answ;
if(delta<0){
answ=nw;
ans=o=no;
}
else if(exp(-delta/t)*32767>rand()) o=no;
t*=0.9999;
}
}
void work(){
int now=1,pt=1,xx=1,yy=1; //随便搞一个矩阵作为初始矩阵
for(reg int i=1;i<=n*m;++i){
o.a[xx][yy]=now;
if(yy==m) yy=0,++xx;
if(pt>=p[now]){
pt=0;
++now;
}
++yy;++pt;
}
o.a[n][m]=c;ans=o;
for(reg int i=1;i<=10;++i) SA();
}
int main(){
srand(1007);
scanf("%d%d%d",&n,&m,&c);
for(reg int i=1;i<=c;++i)
scanf("%d",&p[i]);
work();
for(reg int i=1;i<=n;++i){
for(reg int j=1;j<=m;++j)
printf("%d ",ans.a[i][j]);
puts("");
}
// printf("%d",calc(ans));
}

luogu P3936 Coloring的更多相关文章

  1. 题解 洛谷P3936 Coloring

    考虑搜索,发现复杂度爆炸        贪心,正确性过低(~~实测爆炸~~) 于是,~~发现~~这题是模拟退火 这里不讲解退火的定义了,初学退火可以去平衡点 退火本身维护一个答案图像,答案的q,当前图 ...

  2. Luogu 魔法学院杯-第二弹(萌新的第一法blog)

    虽然有点久远  还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题  沉迷游戏,伤感情 #include <queue> ...

  3. luogu p1268 树的重量——构造,真正考验编程能力

    题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...

  4. Codeforces Round #369 (Div. 2)---C - Coloring Trees (很妙的DP题)

    题目链接 http://codeforces.com/contest/711/problem/C Description ZS the Coder and Chris the Baboon has a ...

  5. CF149D. Coloring Brackets[区间DP !]

    题意:给括号匹配涂色,红色蓝色或不涂,要求见原题,求方案数 区间DP 用栈先处理匹配 f[i][j][0/1/2][0/1/2]表示i到ji涂色和j涂色的方案数 l和r匹配的话,转移到(l+1,r-1 ...

  6. Codeforces Round #369 (Div. 2) C. Coloring Trees DP

    C. Coloring Trees   ZS the Coder and Chris the Baboon has arrived at Udayland! They walked in the pa ...

  7. CodeForces #369 C. Coloring Trees DP

    题目链接:C. Coloring Trees 题意:给出n棵树的颜色,有些树被染了,有些没有.现在让你把没被染色的树染色.使得beauty = k.问,最少使用的颜料是多少.   K:连续的颜色为一组 ...

  8. CodeForces 149D Coloring Brackets

    Coloring Brackets time limit per test: 2 seconds memory limit per test: 256 megabytes input: standar ...

  9. C. Coloring Trees DP

    传送门:http://codeforces.com/problemset/problem/711/C 题目: C. Coloring Trees time limit per test 2 secon ...

随机推荐

  1. 关闭同一网络内的windows主机

    声明这是技术讨论!切勿用来攻击别人,一切法律后果自负! 1. 在windows的cmd命令行下操作(如下操作都是以windows的机器在为主) net view #显示同一网络同所有主机 2. 打开远 ...

  2. 中文保存在properties乱码的解决

    方法:将中文转换为Native/ASCII编码:(比较好的一种解决方法,也必须设置好properties的字符编码(utf-8):已经试验成功) 网站:http://tool.oschina.net/ ...

  3. 深入理解Three.js中透视投影照相机PerspectiveCamera

    前言 在开始正式讲解透视摄像机前,我们先来理理three.js建模的流程.我们在开始创建一个模型的时候,首先需要创建我们模型需要的物体,这个物体可以是three.js中已经为我们封装好的,比如正方体, ...

  4. response向客户端写入数据

    1.写入文字: protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Servle ...

  5. C++基础之迭代器

    迭代器的分类 插入迭代器(insert iterator):绑定一个容器上后可以向容器中插入元素: 流迭代器(stream iterator):绑定在输入输出流中,可以遍历关联的流: 反向迭代器(re ...

  6. Mysql学习笔记整理之选用B+tree结构

    为什么mysql不使用平衡二叉树? 数据处的深度决定着他的IO操作次数,IO操作耗时大 每一个磁盘块保存的数据量太小 B+Tree和B-Tree的区别? B+树几点关键字搜索采用闭合区间 B+树非叶节 ...

  7. MySQL性能优化以及常用命令

    1.将查询操作SELECT中WHERE条件后面和排序字段建立索引 2.按需查询,需要哪个字段就查哪个字段,禁止使用"SELECT * " 3.数据库引擎最好选用InnoDB,少用M ...

  8. 设计模式之UML类图以及类间关系

    类图是描述系统中的类,以及各个类之间的关系的静态视图.能够让我们在正确编写代码以前对系统有一个全面的认识.类图是一种模型类型,确切的说,是一种静态模型类型.类图表示类.接口和它们之间的协作关系. 以下 ...

  9. 死磕 java线程系列之创建线程的8种方式

    (手机横屏看源码更方便) 问题 (1)创建线程有哪几种方式? (2)它们分别有什么运用场景? 简介 创建线程,是多线程编程中最基本的操作,彤哥总结了一下,大概有8种创建线程的方式,你知道吗? 继承Th ...

  10. Disruptor—核心概念及体验

    本文基于最新的3.4.2的版本文档进行翻译,翻译自: https://github.com/LMAX-Exchange/disruptor/wiki/Introduction https://gith ...